@odoo/o-spreadsheet 18.0.15 → 18.0.17
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 +337 -188
- package/dist/o-spreadsheet.d.ts +31 -15
- package/dist/o-spreadsheet.esm.js +337 -188
- package/dist/o-spreadsheet.iife.js +337 -188
- package/dist/o-spreadsheet.iife.min.js +350 -350
- package/dist/o_spreadsheet.xml +4 -3
- package/package.json +3 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 18.0.
|
|
6
|
-
* @date 2025-02-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.0.17
|
|
6
|
+
* @date 2025-02-25T05:58:39.632Z
|
|
7
|
+
* @hash 2ee4347
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -2066,17 +2066,7 @@ function toZoneWithoutBoundaryChanges(xc) {
|
|
|
2066
2066
|
*/
|
|
2067
2067
|
function toUnboundedZone(xc) {
|
|
2068
2068
|
const zone = toZoneWithoutBoundaryChanges(xc);
|
|
2069
|
-
|
|
2070
|
-
const tmp = zone.left;
|
|
2071
|
-
zone.left = zone.right;
|
|
2072
|
-
zone.right = tmp;
|
|
2073
|
-
}
|
|
2074
|
-
if (zone.bottom !== undefined && zone.bottom < zone.top) {
|
|
2075
|
-
const tmp = zone.top;
|
|
2076
|
-
zone.top = zone.bottom;
|
|
2077
|
-
zone.bottom = tmp;
|
|
2078
|
-
}
|
|
2079
|
-
return zone;
|
|
2069
|
+
return reorderZone(zone);
|
|
2080
2070
|
}
|
|
2081
2071
|
/**
|
|
2082
2072
|
* Convert from a cartesian reference to a Zone.
|
|
@@ -2350,11 +2340,11 @@ function positions(zone) {
|
|
|
2350
2340
|
return positions;
|
|
2351
2341
|
}
|
|
2352
2342
|
function reorderZone(zone) {
|
|
2353
|
-
if (zone.left > zone.right) {
|
|
2354
|
-
zone = { left: zone.right, right: zone.left
|
|
2343
|
+
if (zone.right !== undefined && zone.left > zone.right) {
|
|
2344
|
+
zone = { ...zone, left: zone.right, right: zone.left };
|
|
2355
2345
|
}
|
|
2356
|
-
if (zone.top > zone.bottom) {
|
|
2357
|
-
zone = {
|
|
2346
|
+
if (zone.bottom !== undefined && zone.top > zone.bottom) {
|
|
2347
|
+
zone = { ...zone, top: zone.bottom, bottom: zone.top };
|
|
2358
2348
|
}
|
|
2359
2349
|
return zone;
|
|
2360
2350
|
}
|
|
@@ -3248,12 +3238,12 @@ function isTargetDependent(cmd) {
|
|
|
3248
3238
|
function isRangeDependant(cmd) {
|
|
3249
3239
|
return "ranges" in cmd;
|
|
3250
3240
|
}
|
|
3251
|
-
function isZoneDependent(cmd) {
|
|
3252
|
-
return "zone" in cmd;
|
|
3253
|
-
}
|
|
3254
3241
|
function isPositionDependent(cmd) {
|
|
3255
3242
|
return "col" in cmd && "row" in cmd && "sheetId" in cmd;
|
|
3256
3243
|
}
|
|
3244
|
+
function isZoneDependent(cmd) {
|
|
3245
|
+
return "sheetId" in cmd && "zone" in cmd;
|
|
3246
|
+
}
|
|
3257
3247
|
const invalidateEvaluationCommands = new Set([
|
|
3258
3248
|
"RENAME_SHEET",
|
|
3259
3249
|
"DELETE_SHEET",
|
|
@@ -3265,6 +3255,7 @@ const invalidateEvaluationCommands = new Set([
|
|
|
3265
3255
|
"REDO",
|
|
3266
3256
|
"ADD_MERGE",
|
|
3267
3257
|
"REMOVE_MERGE",
|
|
3258
|
+
"DUPLICATE_SHEET",
|
|
3268
3259
|
"UPDATE_LOCALE",
|
|
3269
3260
|
"ADD_PIVOT",
|
|
3270
3261
|
"UPDATE_PIVOT",
|
|
@@ -3293,7 +3284,6 @@ const invalidateChartEvaluationCommands = new Set([
|
|
|
3293
3284
|
]);
|
|
3294
3285
|
const invalidateDependenciesCommands = new Set(["MOVE_RANGES"]);
|
|
3295
3286
|
const invalidateCFEvaluationCommands = new Set([
|
|
3296
|
-
"DUPLICATE_SHEET",
|
|
3297
3287
|
"EVALUATE_CELLS",
|
|
3298
3288
|
"ADD_CONDITIONAL_FORMAT",
|
|
3299
3289
|
"REMOVE_CONDITIONAL_FORMAT",
|
|
@@ -3462,6 +3452,7 @@ exports.CommandResult = void 0;
|
|
|
3462
3452
|
CommandResult["InvalidRange"] = "InvalidRange";
|
|
3463
3453
|
CommandResult["InvalidZones"] = "InvalidZones";
|
|
3464
3454
|
CommandResult["InvalidSheetId"] = "InvalidSheetId";
|
|
3455
|
+
CommandResult["InvalidCellId"] = "InvalidCellId";
|
|
3465
3456
|
CommandResult["InvalidFigureId"] = "InvalidFigureId";
|
|
3466
3457
|
CommandResult["InputAlreadyFocused"] = "InputAlreadyFocused";
|
|
3467
3458
|
CommandResult["MaximumRangesReached"] = "MaximumRangesReached";
|
|
@@ -6347,20 +6338,53 @@ class UuidGenerator {
|
|
|
6347
6338
|
setIsFastStrategy(isFast) {
|
|
6348
6339
|
this.isFastIdStrategy = isFast;
|
|
6349
6340
|
}
|
|
6341
|
+
/**
|
|
6342
|
+
* Generates a custom UUID using a simple 36^12 method (8-character alphanumeric string with lowercase letters)
|
|
6343
|
+
* This has a higher chance of collision than a UUIDv4, but not only faster to generate than an UUIDV4,
|
|
6344
|
+
* it also has a smaller size, which is preferable to alleviate the overall data size.
|
|
6345
|
+
*
|
|
6346
|
+
* This method is preferable when generating uuids for the core data (sheetId, figureId, etc)
|
|
6347
|
+
* as they will appear several times in the revisions and local history.
|
|
6348
|
+
*
|
|
6349
|
+
*/
|
|
6350
|
+
smallUuid() {
|
|
6351
|
+
if (this.isFastIdStrategy) {
|
|
6352
|
+
this.fastIdStart++;
|
|
6353
|
+
return String(this.fastIdStart);
|
|
6354
|
+
}
|
|
6355
|
+
else if (window.crypto) {
|
|
6356
|
+
return "10000000-1000".replace(/[01]/g, (c) => {
|
|
6357
|
+
const n = Number(c);
|
|
6358
|
+
return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
|
|
6359
|
+
});
|
|
6360
|
+
}
|
|
6361
|
+
else {
|
|
6362
|
+
// mainly for jest and other browsers that do not have the crypto functionality
|
|
6363
|
+
return "xxxxxxxx-xxxx".replace(/[xy]/g, function (c) {
|
|
6364
|
+
var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
|
|
6365
|
+
return v.toString(16);
|
|
6366
|
+
});
|
|
6367
|
+
}
|
|
6368
|
+
}
|
|
6369
|
+
/**
|
|
6370
|
+
* Generates an UUIDV4, has astronomically low chance of collision, but is larger in size than the smallUuid.
|
|
6371
|
+
* This method should be used when you need to avoid collisions at all costs, like the id of a revision.
|
|
6372
|
+
*/
|
|
6350
6373
|
uuidv4() {
|
|
6351
6374
|
if (this.isFastIdStrategy) {
|
|
6352
6375
|
this.fastIdStart++;
|
|
6353
6376
|
return String(this.fastIdStart);
|
|
6354
|
-
//@ts-ignore
|
|
6355
6377
|
}
|
|
6356
|
-
else if (window.crypto
|
|
6357
|
-
|
|
6358
|
-
|
|
6378
|
+
else if (window.crypto) {
|
|
6379
|
+
return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) => {
|
|
6380
|
+
const n = Number(c);
|
|
6381
|
+
return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
|
|
6382
|
+
});
|
|
6359
6383
|
}
|
|
6360
6384
|
else {
|
|
6361
6385
|
// mainly for jest and other browsers that do not have the crypto functionality
|
|
6362
6386
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
|
|
6363
|
-
var r = (Math.random() * 16) | 0, v = c
|
|
6387
|
+
var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
|
|
6364
6388
|
return v.toString(16);
|
|
6365
6389
|
});
|
|
6366
6390
|
}
|
|
@@ -8339,7 +8363,7 @@ class ChartClipboardHandler extends AbstractFigureClipboardHandler {
|
|
|
8339
8363
|
};
|
|
8340
8364
|
}
|
|
8341
8365
|
getPasteTarget(sheetId, target, content, options) {
|
|
8342
|
-
const newId = new UuidGenerator().
|
|
8366
|
+
const newId = new UuidGenerator().smallUuid();
|
|
8343
8367
|
return { zones: [], figureId: newId, sheetId };
|
|
8344
8368
|
}
|
|
8345
8369
|
paste(target, clippedContent, options) {
|
|
@@ -8505,7 +8529,7 @@ class ConditionalFormatClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8505
8529
|
if (!targetCF && queuedCfs) {
|
|
8506
8530
|
targetCF = queuedCfs.find((queued) => queued.cf.stopIfTrue === originCF.stopIfTrue && deepEquals(queued.cf.rule, originCF.rule))?.cf;
|
|
8507
8531
|
}
|
|
8508
|
-
return targetCF || { ...originCF, id: this.uuidGenerator.
|
|
8532
|
+
return targetCF || { ...originCF, id: this.uuidGenerator.smallUuid(), ranges: [] };
|
|
8509
8533
|
}
|
|
8510
8534
|
}
|
|
8511
8535
|
|
|
@@ -8598,7 +8622,7 @@ class DataValidationClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8598
8622
|
}
|
|
8599
8623
|
return (targetRule || {
|
|
8600
8624
|
...originRule,
|
|
8601
|
-
id: newId ? this.uuidGenerator.
|
|
8625
|
+
id: newId ? this.uuidGenerator.smallUuid() : originRule.id,
|
|
8602
8626
|
ranges: [],
|
|
8603
8627
|
});
|
|
8604
8628
|
}
|
|
@@ -8660,7 +8684,7 @@ class ImageClipboardHandler extends AbstractFigureClipboardHandler {
|
|
|
8660
8684
|
};
|
|
8661
8685
|
}
|
|
8662
8686
|
getPasteTarget(sheetId, target, content, options) {
|
|
8663
|
-
const newId = new UuidGenerator().
|
|
8687
|
+
const newId = new UuidGenerator().smallUuid();
|
|
8664
8688
|
return { sheetId, zones: [], figureId: newId };
|
|
8665
8689
|
}
|
|
8666
8690
|
paste(target, clippedContent, options) {
|
|
@@ -9639,6 +9663,9 @@ function getTrendDatasetForBarChart(config, dataset) {
|
|
|
9639
9663
|
const filteredValues = [];
|
|
9640
9664
|
const filteredLabels = [];
|
|
9641
9665
|
const labels = [];
|
|
9666
|
+
if (dataset.hidden) {
|
|
9667
|
+
return;
|
|
9668
|
+
}
|
|
9642
9669
|
for (let i = 0; i < dataset.data.length; i++) {
|
|
9643
9670
|
if (typeof dataset.data[i] === "number") {
|
|
9644
9671
|
filteredValues.push(dataset.data[i]);
|
|
@@ -11974,6 +12001,25 @@ const LN = {
|
|
|
11974
12001
|
isExported: true,
|
|
11975
12002
|
};
|
|
11976
12003
|
// -----------------------------------------------------------------------------
|
|
12004
|
+
// LOG
|
|
12005
|
+
// -----------------------------------------------------------------------------
|
|
12006
|
+
const LOG = {
|
|
12007
|
+
description: _t("The logarithm of a number, for a given base."),
|
|
12008
|
+
args: [
|
|
12009
|
+
arg("value (number)", _t("The value for which to calculate the logarithm.")),
|
|
12010
|
+
arg("base (number, default=10)", _t("The base of the logarithm.")),
|
|
12011
|
+
],
|
|
12012
|
+
compute: function (value, base = { value: 10 }) {
|
|
12013
|
+
const _value = toNumber(value, this.locale);
|
|
12014
|
+
const _base = toNumber(base, this.locale);
|
|
12015
|
+
assert(() => _value > 0, _t("The value (%s) must be strictly positive.", _value.toString()));
|
|
12016
|
+
assert(() => _base > 0, _t("The base (%s) must be strictly positive.", _base.toString()));
|
|
12017
|
+
assert(() => _base !== 1, _t("The base must be different from 1."));
|
|
12018
|
+
return Math.log10(_value) / Math.log10(_base);
|
|
12019
|
+
},
|
|
12020
|
+
isExported: true,
|
|
12021
|
+
};
|
|
12022
|
+
// -----------------------------------------------------------------------------
|
|
11977
12023
|
// MOD
|
|
11978
12024
|
// -----------------------------------------------------------------------------
|
|
11979
12025
|
function mod(dividend, divisor) {
|
|
@@ -12513,6 +12559,7 @@ var math = /*#__PURE__*/Object.freeze({
|
|
|
12513
12559
|
ISODD: ISODD,
|
|
12514
12560
|
ISO_CEILING: ISO_CEILING,
|
|
12515
12561
|
LN: LN,
|
|
12562
|
+
LOG: LOG,
|
|
12516
12563
|
MOD: MOD,
|
|
12517
12564
|
MUNIT: MUNIT,
|
|
12518
12565
|
ODD: ODD,
|
|
@@ -15062,7 +15109,7 @@ const SORTN = {
|
|
|
15062
15109
|
}
|
|
15063
15110
|
}
|
|
15064
15111
|
},
|
|
15065
|
-
isExported:
|
|
15112
|
+
isExported: false,
|
|
15066
15113
|
};
|
|
15067
15114
|
// -----------------------------------------------------------------------------
|
|
15068
15115
|
// UNIQUE
|
|
@@ -28516,17 +28563,15 @@ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, tr
|
|
|
28516
28563
|
plugins: [],
|
|
28517
28564
|
};
|
|
28518
28565
|
}
|
|
28519
|
-
function getChartLabelFormat(getters, range) {
|
|
28566
|
+
function getChartLabelFormat(getters, range, shouldRemoveFirstLabel) {
|
|
28520
28567
|
if (!range)
|
|
28521
28568
|
return undefined;
|
|
28522
|
-
const { sheetId, zone
|
|
28523
|
-
|
|
28524
|
-
|
|
28525
|
-
|
|
28526
|
-
return format;
|
|
28527
|
-
}
|
|
28569
|
+
const { sheetId, zone } = range;
|
|
28570
|
+
const formats = positions(zone).map((position) => getters.getEvaluatedCell({ sheetId, ...position }).format);
|
|
28571
|
+
if (shouldRemoveFirstLabel) {
|
|
28572
|
+
formats.shift();
|
|
28528
28573
|
}
|
|
28529
|
-
return undefined;
|
|
28574
|
+
return formats.find((format) => format !== undefined);
|
|
28530
28575
|
}
|
|
28531
28576
|
function getChartLabelValues(getters, dataSets, labelRange) {
|
|
28532
28577
|
let labels = { values: [], formattedValues: [] };
|
|
@@ -28581,10 +28626,8 @@ function getChartDatasetFormat(getters, dataSets) {
|
|
|
28581
28626
|
function getChartDatasetValues(getters, dataSets) {
|
|
28582
28627
|
const datasetValues = [];
|
|
28583
28628
|
for (const [dsIndex, ds] of Object.entries(dataSets)) {
|
|
28584
|
-
if (getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left)) {
|
|
28585
|
-
continue;
|
|
28586
|
-
}
|
|
28587
28629
|
let label;
|
|
28630
|
+
let hidden = getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left);
|
|
28588
28631
|
if (ds.labelCell) {
|
|
28589
28632
|
const labelRange = ds.labelCell;
|
|
28590
28633
|
const cell = labelRange
|
|
@@ -28611,9 +28654,9 @@ function getChartDatasetValues(getters, dataSets) {
|
|
|
28611
28654
|
data.fill(1);
|
|
28612
28655
|
}
|
|
28613
28656
|
else if (data.every((cell) => cell === undefined || cell === null || !isNumber(cell.toString(), DEFAULT_LOCALE))) {
|
|
28614
|
-
|
|
28657
|
+
hidden = true;
|
|
28615
28658
|
}
|
|
28616
|
-
datasetValues.push({ data, label });
|
|
28659
|
+
datasetValues.push({ data, label, hidden });
|
|
28617
28660
|
}
|
|
28618
28661
|
return datasetValues;
|
|
28619
28662
|
}
|
|
@@ -28680,6 +28723,20 @@ const backgroundColorChartJSPlugin = {
|
|
|
28680
28723
|
ctx.restore();
|
|
28681
28724
|
},
|
|
28682
28725
|
};
|
|
28726
|
+
function getChartJsLegend(fontColor, legend = {}) {
|
|
28727
|
+
return {
|
|
28728
|
+
...legend,
|
|
28729
|
+
labels: {
|
|
28730
|
+
color: fontColor,
|
|
28731
|
+
filter: (legendItem, data) => {
|
|
28732
|
+
return "datasetIndex" in legendItem
|
|
28733
|
+
? !data.datasets[legendItem.datasetIndex].hidden
|
|
28734
|
+
: true;
|
|
28735
|
+
},
|
|
28736
|
+
...legend.labels,
|
|
28737
|
+
},
|
|
28738
|
+
};
|
|
28739
|
+
}
|
|
28683
28740
|
|
|
28684
28741
|
class BarChart extends AbstractChart {
|
|
28685
28742
|
dataSets;
|
|
@@ -28814,9 +28871,7 @@ function createBarChartRuntime(chart, getters) {
|
|
|
28814
28871
|
const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
|
|
28815
28872
|
let labels = labelValues.formattedValues;
|
|
28816
28873
|
let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
|
|
28817
|
-
if (chart.dataSetsHaveTitle
|
|
28818
|
-
dataSetsValues[0] &&
|
|
28819
|
-
labels.length > dataSetsValues[0].data.length) {
|
|
28874
|
+
if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
|
|
28820
28875
|
labels.shift();
|
|
28821
28876
|
}
|
|
28822
28877
|
({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
|
|
@@ -28831,9 +28886,7 @@ function createBarChartRuntime(chart, getters) {
|
|
|
28831
28886
|
...localeFormat,
|
|
28832
28887
|
horizontalChart: chart.horizontal,
|
|
28833
28888
|
});
|
|
28834
|
-
const legend =
|
|
28835
|
-
labels: { color: fontColor },
|
|
28836
|
-
};
|
|
28889
|
+
const legend = getChartJsLegend(fontColor);
|
|
28837
28890
|
if (chart.legendPosition === "none") {
|
|
28838
28891
|
legend.display = false;
|
|
28839
28892
|
}
|
|
@@ -28897,11 +28950,12 @@ function createBarChartRuntime(chart, getters) {
|
|
|
28897
28950
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
28898
28951
|
const trendDatasets = [];
|
|
28899
28952
|
for (const index in dataSetsValues) {
|
|
28900
|
-
const { label, data } = dataSetsValues[index];
|
|
28953
|
+
const { label, data, hidden } = dataSetsValues[index];
|
|
28901
28954
|
const color = colors.next();
|
|
28902
28955
|
const dataset = {
|
|
28903
28956
|
label,
|
|
28904
28957
|
data,
|
|
28958
|
+
hidden,
|
|
28905
28959
|
borderColor: definition.background || BACKGROUND_CHART_COLOR,
|
|
28906
28960
|
borderWidth: definition.stacked ? 1 : 0,
|
|
28907
28961
|
backgroundColor: color,
|
|
@@ -29085,8 +29139,8 @@ function fixEmptyLabelsForDateCharts(labels, dataSetsValues) {
|
|
|
29085
29139
|
}
|
|
29086
29140
|
return { labels: newLabels, dataSetsValues: newDatasets };
|
|
29087
29141
|
}
|
|
29088
|
-
function canChartParseLabels(
|
|
29089
|
-
return canBeDateChart(
|
|
29142
|
+
function canChartParseLabels(chart, getters) {
|
|
29143
|
+
return canBeDateChart(chart, getters) || canBeLinearChart(chart, getters);
|
|
29090
29144
|
}
|
|
29091
29145
|
function getChartAxisType(chart, getters) {
|
|
29092
29146
|
if (isDateChart(chart, getters) && isLuxonTimeAdapterInstalled()) {
|
|
@@ -29098,23 +29152,26 @@ function getChartAxisType(chart, getters) {
|
|
|
29098
29152
|
return "category";
|
|
29099
29153
|
}
|
|
29100
29154
|
function isDateChart(chart, getters) {
|
|
29101
|
-
return !chart.labelsAsText && canBeDateChart(chart
|
|
29155
|
+
return !chart.labelsAsText && canBeDateChart(chart, getters);
|
|
29102
29156
|
}
|
|
29103
29157
|
function isLinearChart(chart, getters) {
|
|
29104
|
-
return !chart.labelsAsText && canBeLinearChart(chart
|
|
29158
|
+
return !chart.labelsAsText && canBeLinearChart(chart, getters);
|
|
29105
29159
|
}
|
|
29106
|
-
function canBeDateChart(
|
|
29107
|
-
if (!labelRange || !canBeLinearChart(
|
|
29160
|
+
function canBeDateChart(chart, getters) {
|
|
29161
|
+
if (!chart.labelRange || !canBeLinearChart(chart, getters)) {
|
|
29108
29162
|
return false;
|
|
29109
29163
|
}
|
|
29110
|
-
const labelFormat = getChartLabelFormat(getters, labelRange);
|
|
29164
|
+
const labelFormat = getChartLabelFormat(getters, chart.labelRange, shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle));
|
|
29111
29165
|
return Boolean(labelFormat && timeFormatLuxonCompatible.test(labelFormat));
|
|
29112
29166
|
}
|
|
29113
|
-
function canBeLinearChart(
|
|
29114
|
-
if (!labelRange) {
|
|
29167
|
+
function canBeLinearChart(chart, getters) {
|
|
29168
|
+
if (!chart.labelRange) {
|
|
29115
29169
|
return false;
|
|
29116
29170
|
}
|
|
29117
|
-
const labels = getters.getRangeValues(labelRange);
|
|
29171
|
+
const labels = getters.getRangeValues(chart.labelRange);
|
|
29172
|
+
if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
|
|
29173
|
+
labels.shift();
|
|
29174
|
+
}
|
|
29118
29175
|
if (labels.some((label) => isNaN(Number(label)) && label)) {
|
|
29119
29176
|
return false;
|
|
29120
29177
|
}
|
|
@@ -29142,6 +29199,9 @@ function getTrendDatasetForLineChart(config, dataset, axisType, locale) {
|
|
|
29142
29199
|
const filteredLabels = [];
|
|
29143
29200
|
const labels = [];
|
|
29144
29201
|
const datasetLength = dataset.data.length;
|
|
29202
|
+
if (dataset.hidden) {
|
|
29203
|
+
return;
|
|
29204
|
+
}
|
|
29145
29205
|
if (datasetLength < 2) {
|
|
29146
29206
|
return;
|
|
29147
29207
|
}
|
|
@@ -29198,9 +29258,8 @@ function createLineOrScatterChartRuntime(chart, getters) {
|
|
|
29198
29258
|
const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
|
|
29199
29259
|
let labels = axisType === "linear" ? labelValues.values : labelValues.formattedValues;
|
|
29200
29260
|
let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
|
|
29201
|
-
|
|
29202
|
-
|
|
29203
|
-
labels.length > dataSetsValues[0].data.length) {
|
|
29261
|
+
const removeFirstLabel = shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle);
|
|
29262
|
+
if (removeFirstLabel) {
|
|
29204
29263
|
labels.shift();
|
|
29205
29264
|
}
|
|
29206
29265
|
({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
|
|
@@ -29216,9 +29275,8 @@ function createLineOrScatterChartRuntime(chart, getters) {
|
|
|
29216
29275
|
const options = { format: dataSetFormat, locale, truncateLabels };
|
|
29217
29276
|
const fontColor = chartFontColor(chart.background);
|
|
29218
29277
|
const config = getDefaultChartJsRuntime(chart, labels, fontColor, options);
|
|
29219
|
-
const legend = {
|
|
29278
|
+
const legend = getChartJsLegend(fontColor, {
|
|
29220
29279
|
labels: {
|
|
29221
|
-
color: fontColor,
|
|
29222
29280
|
generateLabels(chart) {
|
|
29223
29281
|
// color the legend labels with the dataset color, without any transparency
|
|
29224
29282
|
const { data } = chart;
|
|
@@ -29229,7 +29287,7 @@ function createLineOrScatterChartRuntime(chart, getters) {
|
|
|
29229
29287
|
return labels;
|
|
29230
29288
|
},
|
|
29231
29289
|
},
|
|
29232
|
-
};
|
|
29290
|
+
});
|
|
29233
29291
|
if (chart.legendPosition === "none") {
|
|
29234
29292
|
legend.display = false;
|
|
29235
29293
|
}
|
|
@@ -29290,12 +29348,7 @@ function createLineOrScatterChartRuntime(chart, getters) {
|
|
|
29290
29348
|
background: chart.background,
|
|
29291
29349
|
callback: formatTickValue(options),
|
|
29292
29350
|
};
|
|
29293
|
-
|
|
29294
|
-
dataSetsValues[0] &&
|
|
29295
|
-
labels.length > dataSetsValues[0].data.length) {
|
|
29296
|
-
labels.shift();
|
|
29297
|
-
}
|
|
29298
|
-
const labelFormat = getChartLabelFormat(getters, chart.labelRange);
|
|
29351
|
+
const labelFormat = getChartLabelFormat(getters, chart.labelRange, removeFirstLabel);
|
|
29299
29352
|
if (axisType === "time") {
|
|
29300
29353
|
const axis = {
|
|
29301
29354
|
type: "time",
|
|
@@ -29334,7 +29387,7 @@ function createLineOrScatterChartRuntime(chart, getters) {
|
|
|
29334
29387
|
const cumulative = "cumulative" in chart ? chart.cumulative : false;
|
|
29335
29388
|
const definition = chart.getDefinition();
|
|
29336
29389
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
29337
|
-
for (let [index, { label, data }] of dataSetsValues.entries()) {
|
|
29390
|
+
for (let [index, { label, data, hidden }] of dataSetsValues.entries()) {
|
|
29338
29391
|
const color = colors.next();
|
|
29339
29392
|
let backgroundRGBA = colorToRGBA(color);
|
|
29340
29393
|
if (areaChart) {
|
|
@@ -29358,6 +29411,7 @@ function createLineOrScatterChartRuntime(chart, getters) {
|
|
|
29358
29411
|
const dataset = {
|
|
29359
29412
|
label,
|
|
29360
29413
|
data,
|
|
29414
|
+
hidden,
|
|
29361
29415
|
tension: 0, // 0 -> render straight lines, which is much faster
|
|
29362
29416
|
borderColor: color,
|
|
29363
29417
|
backgroundColor,
|
|
@@ -29553,9 +29607,7 @@ function createComboChartRuntime(chart, getters) {
|
|
|
29553
29607
|
const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
|
|
29554
29608
|
let labels = labelValues.formattedValues;
|
|
29555
29609
|
let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
|
|
29556
|
-
if (chart.dataSetsHaveTitle
|
|
29557
|
-
dataSetsValues[0] &&
|
|
29558
|
-
labels.length > dataSetsValues[0].data.length) {
|
|
29610
|
+
if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
|
|
29559
29611
|
labels.shift();
|
|
29560
29612
|
}
|
|
29561
29613
|
({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
|
|
@@ -29565,9 +29617,7 @@ function createComboChartRuntime(chart, getters) {
|
|
|
29565
29617
|
const localeFormat = { format: mainDataSetFormat, locale };
|
|
29566
29618
|
const fontColor = chartFontColor(chart.background);
|
|
29567
29619
|
const config = getDefaultChartJsRuntime(chart, labels, fontColor, localeFormat);
|
|
29568
|
-
const legend =
|
|
29569
|
-
labels: { color: fontColor },
|
|
29570
|
-
};
|
|
29620
|
+
const legend = getChartJsLegend(fontColor);
|
|
29571
29621
|
if (chart.legendPosition === "none") {
|
|
29572
29622
|
legend.display = false;
|
|
29573
29623
|
}
|
|
@@ -29631,13 +29681,14 @@ function createComboChartRuntime(chart, getters) {
|
|
|
29631
29681
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
29632
29682
|
let maxLength = 0;
|
|
29633
29683
|
const trendDatasets = [];
|
|
29634
|
-
for (let [index, { label, data }] of dataSetsValues.entries()) {
|
|
29684
|
+
for (let [index, { label, data, hidden }] of dataSetsValues.entries()) {
|
|
29635
29685
|
const design = definition.dataSets[index];
|
|
29636
29686
|
const color = colors.next();
|
|
29637
29687
|
const type = design?.type ?? "line";
|
|
29638
29688
|
const dataset = {
|
|
29639
29689
|
label: design?.label ?? label,
|
|
29640
29690
|
data,
|
|
29691
|
+
hidden,
|
|
29641
29692
|
borderColor: color,
|
|
29642
29693
|
backgroundColor: color,
|
|
29643
29694
|
yAxisID: design?.yAxisId ?? "y",
|
|
@@ -30245,10 +30296,8 @@ function filterNegativeValues(labels, datasets) {
|
|
|
30245
30296
|
function createPieChartRuntime(chart, getters) {
|
|
30246
30297
|
const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
|
|
30247
30298
|
let labels = labelValues.formattedValues;
|
|
30248
|
-
let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
|
|
30249
|
-
if (chart.dataSetsHaveTitle
|
|
30250
|
-
dataSetsValues[0] &&
|
|
30251
|
-
labels.length > dataSetsValues[0].data.length) {
|
|
30299
|
+
let dataSetsValues = getChartDatasetValues(getters, chart.dataSets).filter((dataSet) => !dataSet.hidden);
|
|
30300
|
+
if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
|
|
30252
30301
|
labels.shift();
|
|
30253
30302
|
}
|
|
30254
30303
|
({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
|
|
@@ -30265,7 +30314,7 @@ function createPieChartRuntime(chart, getters) {
|
|
|
30265
30314
|
const dataset = {
|
|
30266
30315
|
label,
|
|
30267
30316
|
data,
|
|
30268
|
-
borderColor:
|
|
30317
|
+
borderColor: chart.background || "#FFFFFF",
|
|
30269
30318
|
backgroundColor,
|
|
30270
30319
|
hoverOffset: 30,
|
|
30271
30320
|
};
|
|
@@ -30394,8 +30443,9 @@ function createPyramidChartRuntime(chart, getters) {
|
|
|
30394
30443
|
const barDef = { ...chart.getDefinition(), type: "bar" };
|
|
30395
30444
|
const barChart = new BarChart(barDef, chart.sheetId, getters);
|
|
30396
30445
|
const barRuntime = createBarChartRuntime(barChart, getters);
|
|
30446
|
+
// align design with filtered datasets
|
|
30397
30447
|
const config = barRuntime.chartJsConfig;
|
|
30398
|
-
let datasets = config.data?.datasets;
|
|
30448
|
+
let datasets = config.data?.datasets.filter((dataSet) => !dataSet.hidden);
|
|
30399
30449
|
if (datasets && datasets[0]) {
|
|
30400
30450
|
datasets[0].data = datasets[0].data.map((value) => (value > 0 ? value : 0));
|
|
30401
30451
|
}
|
|
@@ -30792,10 +30842,8 @@ function getWaterfallConfiguration(chart, labels, dataSeriesLabels, localeFormat
|
|
|
30792
30842
|
function createWaterfallChartRuntime(chart, getters) {
|
|
30793
30843
|
const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
|
|
30794
30844
|
let labels = labelValues.formattedValues;
|
|
30795
|
-
let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
|
|
30796
|
-
if (chart.dataSetsHaveTitle
|
|
30797
|
-
dataSetsValues[0] &&
|
|
30798
|
-
labels.length > dataSetsValues[0].data.length) {
|
|
30845
|
+
let dataSetsValues = getChartDatasetValues(getters, chart.dataSets).filter((ds) => !ds.hidden);
|
|
30846
|
+
if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
|
|
30799
30847
|
labels.shift();
|
|
30800
30848
|
}
|
|
30801
30849
|
({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
|
|
@@ -32291,7 +32339,7 @@ const linkSheet = {
|
|
|
32291
32339
|
const deleteSheet = {
|
|
32292
32340
|
name: _t("Delete"),
|
|
32293
32341
|
isVisible: (env) => {
|
|
32294
|
-
return env.model.getters.
|
|
32342
|
+
return env.model.getters.getVisibleSheetIds().length > 1;
|
|
32295
32343
|
},
|
|
32296
32344
|
execute: (env) => env.askConfirmation(_t("Are you sure you want to delete this sheet?"), () => {
|
|
32297
32345
|
env.model.dispatch("DELETE_SHEET", { sheetId: env.model.getters.getActiveSheetId() });
|
|
@@ -32302,7 +32350,7 @@ const duplicateSheet = {
|
|
|
32302
32350
|
name: _t("Duplicate"),
|
|
32303
32351
|
execute: (env) => {
|
|
32304
32352
|
const sheetIdFrom = env.model.getters.getActiveSheetId();
|
|
32305
|
-
const sheetIdTo = env.model.uuidGenerator.
|
|
32353
|
+
const sheetIdTo = env.model.uuidGenerator.smallUuid();
|
|
32306
32354
|
env.model.dispatch("DUPLICATE_SHEET", {
|
|
32307
32355
|
sheetId: sheetIdFrom,
|
|
32308
32356
|
sheetIdTo,
|
|
@@ -32929,20 +32977,21 @@ function getSmartChartDefinition(zone, getters) {
|
|
|
32929
32977
|
}
|
|
32930
32978
|
// Only display legend for several datasets.
|
|
32931
32979
|
const newLegendPos = dataSetZone.right === dataSetZone.left ? "none" : "top";
|
|
32932
|
-
const
|
|
32933
|
-
|
|
32934
|
-
|
|
32935
|
-
|
|
32936
|
-
|
|
32937
|
-
|
|
32938
|
-
|
|
32939
|
-
|
|
32940
|
-
|
|
32941
|
-
|
|
32942
|
-
|
|
32943
|
-
|
|
32944
|
-
|
|
32945
|
-
|
|
32980
|
+
const lineChartDefinition = {
|
|
32981
|
+
title: {},
|
|
32982
|
+
dataSets,
|
|
32983
|
+
labelsAsText: false,
|
|
32984
|
+
stacked: false,
|
|
32985
|
+
aggregated: false,
|
|
32986
|
+
cumulative: false,
|
|
32987
|
+
labelRange: labelRangeXc,
|
|
32988
|
+
type: "line",
|
|
32989
|
+
dataSetsHaveTitle,
|
|
32990
|
+
legendPosition: newLegendPos,
|
|
32991
|
+
};
|
|
32992
|
+
const chart = new LineChart(lineChartDefinition, sheetId, getters);
|
|
32993
|
+
if (canChartParseLabels(chart, getters)) {
|
|
32994
|
+
return lineChartDefinition;
|
|
32946
32995
|
}
|
|
32947
32996
|
const _dataSets = createDataSets(getters, dataSets, sheetId, dataSetsHaveTitle);
|
|
32948
32997
|
if (singleColumn &&
|
|
@@ -33310,7 +33359,7 @@ const HIDE_ROWS_NAME = (env) => {
|
|
|
33310
33359
|
//------------------------------------------------------------------------------
|
|
33311
33360
|
const CREATE_CHART = (env) => {
|
|
33312
33361
|
const getters = env.model.getters;
|
|
33313
|
-
const id = env.model.uuidGenerator.
|
|
33362
|
+
const id = env.model.uuidGenerator.smallUuid();
|
|
33314
33363
|
const sheetId = getters.getActiveSheetId();
|
|
33315
33364
|
if (getZoneArea(env.model.getters.getSelectedZone()) === 1) {
|
|
33316
33365
|
env.model.selection.selectTableAroundSelection();
|
|
@@ -33333,8 +33382,8 @@ const CREATE_CHART = (env) => {
|
|
|
33333
33382
|
// Pivots
|
|
33334
33383
|
//------------------------------------------------------------------------------
|
|
33335
33384
|
const CREATE_PIVOT = (env) => {
|
|
33336
|
-
const pivotId = env.model.uuidGenerator.
|
|
33337
|
-
const newSheetId = env.model.uuidGenerator.
|
|
33385
|
+
const pivotId = env.model.uuidGenerator.smallUuid();
|
|
33386
|
+
const newSheetId = env.model.uuidGenerator.smallUuid();
|
|
33338
33387
|
const result = env.model.dispatch("INSERT_NEW_PIVOT", { pivotId, newSheetId });
|
|
33339
33388
|
if (result.isSuccessful) {
|
|
33340
33389
|
env.openSidePanel("PivotSidePanel", { pivotId });
|
|
@@ -33393,7 +33442,7 @@ async function requestImage(env) {
|
|
|
33393
33442
|
const CREATE_IMAGE = async (env) => {
|
|
33394
33443
|
if (env.imageProvider) {
|
|
33395
33444
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
33396
|
-
const figureId = env.model.uuidGenerator.
|
|
33445
|
+
const figureId = env.model.uuidGenerator.smallUuid();
|
|
33397
33446
|
const image = await requestImage(env);
|
|
33398
33447
|
if (!image) {
|
|
33399
33448
|
throw new Error("No image provider was given to the environment");
|
|
@@ -33946,7 +33995,7 @@ const insertCheckbox = {
|
|
|
33946
33995
|
ranges,
|
|
33947
33996
|
sheetId,
|
|
33948
33997
|
rule: {
|
|
33949
|
-
id: env.model.uuidGenerator.
|
|
33998
|
+
id: env.model.uuidGenerator.smallUuid(),
|
|
33950
33999
|
criterion: {
|
|
33951
34000
|
type: "isBoolean",
|
|
33952
34001
|
values: [],
|
|
@@ -33962,7 +34011,7 @@ const insertDropdown = {
|
|
|
33962
34011
|
const zones = env.model.getters.getSelectedZones();
|
|
33963
34012
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
33964
34013
|
const ranges = zones.map((zone) => env.model.getters.getRangeDataFromZone(sheetId, zone));
|
|
33965
|
-
const ruleID = env.model.uuidGenerator.
|
|
34014
|
+
const ruleID = env.model.uuidGenerator.smallUuid();
|
|
33966
34015
|
env.model.dispatch("ADD_DATA_VALIDATION_RULE", {
|
|
33967
34016
|
ranges,
|
|
33968
34017
|
sheetId,
|
|
@@ -33993,7 +34042,7 @@ const insertSheet = {
|
|
|
33993
34042
|
execute: (env) => {
|
|
33994
34043
|
const activeSheetId = env.model.getters.getActiveSheetId();
|
|
33995
34044
|
const position = env.model.getters.getSheetIds().indexOf(activeSheetId) + 1;
|
|
33996
|
-
const sheetId = env.model.uuidGenerator.
|
|
34045
|
+
const sheetId = env.model.uuidGenerator.smallUuid();
|
|
33997
34046
|
env.model.dispatch("CREATE_SHEET", { sheetId, position });
|
|
33998
34047
|
env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
|
|
33999
34048
|
},
|
|
@@ -37988,7 +38037,7 @@ class LineConfigPanel extends GenericChartConfigPanel {
|
|
|
37988
38037
|
get canTreatLabelsAsText() {
|
|
37989
38038
|
const chart = this.env.model.getters.getChart(this.props.figureId);
|
|
37990
38039
|
if (chart && chart instanceof LineChart) {
|
|
37991
|
-
return canChartParseLabels(chart
|
|
38040
|
+
return canChartParseLabels(chart, this.env.model.getters);
|
|
37992
38041
|
}
|
|
37993
38042
|
return false;
|
|
37994
38043
|
}
|
|
@@ -38057,7 +38106,7 @@ class ScatterConfigPanel extends GenericChartConfigPanel {
|
|
|
38057
38106
|
get canTreatLabelsAsText() {
|
|
38058
38107
|
const chart = this.env.model.getters.getChart(this.props.figureId);
|
|
38059
38108
|
if (chart && chart instanceof ScatterChart) {
|
|
38060
|
-
return canChartParseLabels(chart
|
|
38109
|
+
return canChartParseLabels(chart, this.env.model.getters);
|
|
38061
38110
|
}
|
|
38062
38111
|
return false;
|
|
38063
38112
|
}
|
|
@@ -39872,7 +39921,7 @@ class ConditionalFormattingEditor extends owl.Component {
|
|
|
39872
39921
|
state;
|
|
39873
39922
|
setup() {
|
|
39874
39923
|
const cf = this.props.editedCf || {
|
|
39875
|
-
id: this.env.model.uuidGenerator.
|
|
39924
|
+
id: this.env.model.uuidGenerator.smallUuid(),
|
|
39876
39925
|
ranges: this.env.model.getters
|
|
39877
39926
|
.getSelectedZones()
|
|
39878
39927
|
.map((zone) => this.env.model.getters.zoneToXC(this.env.model.getters.getActiveSheetId(), zone)),
|
|
@@ -41468,7 +41517,7 @@ class DataValidationEditor extends owl.Component {
|
|
|
41468
41517
|
.getSelectedZones()
|
|
41469
41518
|
.map((zone) => zoneToXc(this.env.model.getters.getUnboundedZone(sheetId, zone)));
|
|
41470
41519
|
return {
|
|
41471
|
-
id: this.env.model.uuidGenerator.
|
|
41520
|
+
id: this.env.model.uuidGenerator.smallUuid(),
|
|
41472
41521
|
criterion: { type: "textContains", values: [""] },
|
|
41473
41522
|
ranges,
|
|
41474
41523
|
};
|
|
@@ -42987,8 +43036,8 @@ class PivotTitleSection extends owl.Component {
|
|
|
42987
43036
|
return this.env.model.getters.getPivotDisplayName(this.props.pivotId);
|
|
42988
43037
|
}
|
|
42989
43038
|
duplicatePivot() {
|
|
42990
|
-
const newPivotId = this.env.model.uuidGenerator.
|
|
42991
|
-
const newSheetId = this.env.model.uuidGenerator.
|
|
43039
|
+
const newPivotId = this.env.model.uuidGenerator.smallUuid();
|
|
43040
|
+
const newSheetId = this.env.model.uuidGenerator.smallUuid();
|
|
42992
43041
|
const result = this.env.model.dispatch("DUPLICATE_PIVOT_IN_NEW_SHEET", {
|
|
42993
43042
|
pivotId: this.props.pivotId,
|
|
42994
43043
|
newPivotId,
|
|
@@ -45553,7 +45602,7 @@ class TableStyleEditorPanel extends owl.Component {
|
|
|
45553
45602
|
this.state.selectedTemplateName = templateName;
|
|
45554
45603
|
}
|
|
45555
45604
|
onConfirm() {
|
|
45556
|
-
const tableStyleId = this.props.styleId || this.env.model.uuidGenerator.
|
|
45605
|
+
const tableStyleId = this.props.styleId || this.env.model.uuidGenerator.smallUuid();
|
|
45557
45606
|
this.env.model.dispatch("CREATE_TABLE_STYLE", {
|
|
45558
45607
|
tableStyleId,
|
|
45559
45608
|
tableStyleName: this.state.styleName,
|
|
@@ -51149,6 +51198,10 @@ class CellPlugin extends CorePlugin {
|
|
|
51149
51198
|
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
|
|
51150
51199
|
case "CLEAR_CELL":
|
|
51151
51200
|
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
|
|
51201
|
+
case "UPDATE_CELL_POSITION":
|
|
51202
|
+
return !cmd.cellId || this.cells[cmd.sheetId]?.[cmd.cellId]
|
|
51203
|
+
? "Success" /* CommandResult.Success */
|
|
51204
|
+
: "InvalidCellId" /* CommandResult.InvalidCellId */;
|
|
51152
51205
|
default:
|
|
51153
51206
|
return "Success" /* CommandResult.Success */;
|
|
51154
51207
|
}
|
|
@@ -51193,6 +51246,9 @@ class CellPlugin extends CorePlugin {
|
|
|
51193
51246
|
case "DELETE_CONTENT":
|
|
51194
51247
|
this.clearZones(cmd.sheetId, cmd.target);
|
|
51195
51248
|
break;
|
|
51249
|
+
case "DELETE_SHEET": {
|
|
51250
|
+
this.history.update("cells", cmd.sheetId, undefined);
|
|
51251
|
+
}
|
|
51196
51252
|
}
|
|
51197
51253
|
}
|
|
51198
51254
|
clearZones(sheetId, zones) {
|
|
@@ -52414,8 +52470,14 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
52414
52470
|
allowDispatch(cmd) {
|
|
52415
52471
|
switch (cmd.type) {
|
|
52416
52472
|
case "ADD_DATA_VALIDATION_RULE":
|
|
52473
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
52474
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
52475
|
+
}
|
|
52417
52476
|
return this.checkValidations(cmd, this.chainValidations(this.checkEmptyRange, this.checkCriterionTypeIsValid, this.checkCriterionHasValidNumberOfValues, this.checkCriterionValuesAreValid));
|
|
52418
52477
|
case "REMOVE_DATA_VALIDATION_RULE":
|
|
52478
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
52479
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
52480
|
+
}
|
|
52419
52481
|
if (!this.rules[cmd.sheetId].find((rule) => rule.id === cmd.id)) {
|
|
52420
52482
|
return "UnknownDataValidationRule" /* CommandResult.UnknownDataValidationRule */;
|
|
52421
52483
|
}
|
|
@@ -52635,6 +52697,7 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
52635
52697
|
class FigurePlugin extends CorePlugin {
|
|
52636
52698
|
static getters = ["getFigures", "getFigure", "getFigureSheetId"];
|
|
52637
52699
|
figures = {};
|
|
52700
|
+
insertionOrders = []; // TODO use a list in master
|
|
52638
52701
|
// ---------------------------------------------------------------------------
|
|
52639
52702
|
// Command Handling
|
|
52640
52703
|
// ---------------------------------------------------------------------------
|
|
@@ -52737,11 +52800,14 @@ class FigurePlugin extends CorePlugin {
|
|
|
52737
52800
|
}
|
|
52738
52801
|
addFigure(figure, sheetId) {
|
|
52739
52802
|
this.history.update("figures", sheetId, figure.id, figure);
|
|
52803
|
+
this.history.update("insertionOrders", this.insertionOrders.length, figure.id);
|
|
52740
52804
|
}
|
|
52741
52805
|
deleteSheet(sheetId) {
|
|
52806
|
+
this.history.update("insertionOrders", this.insertionOrders.filter((id) => !this.figures[sheetId]?.[id]));
|
|
52742
52807
|
this.history.update("figures", sheetId, undefined);
|
|
52743
52808
|
}
|
|
52744
52809
|
removeFigure(id, sheetId) {
|
|
52810
|
+
this.history.update("insertionOrders", this.insertionOrders.filter((figureId) => figureId !== id));
|
|
52745
52811
|
this.history.update("figures", sheetId, id, undefined);
|
|
52746
52812
|
}
|
|
52747
52813
|
checkFigureExists(sheetId, figureId) {
|
|
@@ -52760,7 +52826,14 @@ class FigurePlugin extends CorePlugin {
|
|
|
52760
52826
|
// Getters
|
|
52761
52827
|
// ---------------------------------------------------------------------------
|
|
52762
52828
|
getFigures(sheetId) {
|
|
52763
|
-
|
|
52829
|
+
const figures = [];
|
|
52830
|
+
for (const figureId of this.insertionOrders) {
|
|
52831
|
+
const figure = this.figures[sheetId]?.[figureId];
|
|
52832
|
+
if (figure) {
|
|
52833
|
+
figures.push(figure);
|
|
52834
|
+
}
|
|
52835
|
+
}
|
|
52836
|
+
return figures;
|
|
52764
52837
|
}
|
|
52765
52838
|
getFigure(sheetId, figureId) {
|
|
52766
52839
|
return this.figures[sheetId]?.[figureId];
|
|
@@ -52773,11 +52846,9 @@ class FigurePlugin extends CorePlugin {
|
|
|
52773
52846
|
// ---------------------------------------------------------------------------
|
|
52774
52847
|
import(data) {
|
|
52775
52848
|
for (let sheet of data.sheets) {
|
|
52776
|
-
const figures
|
|
52777
|
-
|
|
52778
|
-
|
|
52779
|
-
});
|
|
52780
|
-
this.figures[sheet.id] = figures;
|
|
52849
|
+
for (const figure of sheet.figures) {
|
|
52850
|
+
this.addFigure(figure, sheet.id);
|
|
52851
|
+
}
|
|
52781
52852
|
}
|
|
52782
52853
|
}
|
|
52783
52854
|
export(data) {
|
|
@@ -54203,6 +54274,9 @@ class SheetPlugin extends CorePlugin {
|
|
|
54203
54274
|
case "CREATE_SHEET": {
|
|
54204
54275
|
return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
|
|
54205
54276
|
}
|
|
54277
|
+
case "DUPLICATE_SHEET": {
|
|
54278
|
+
return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
|
|
54279
|
+
}
|
|
54206
54280
|
case "MOVE_SHEET":
|
|
54207
54281
|
try {
|
|
54208
54282
|
const currentIndex = this.orderedSheetIds.findIndex((id) => id === cmd.sheetId);
|
|
@@ -54219,7 +54293,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
54219
54293
|
? "Success" /* CommandResult.Success */
|
|
54220
54294
|
: "InvalidColor" /* CommandResult.InvalidColor */;
|
|
54221
54295
|
case "DELETE_SHEET":
|
|
54222
|
-
return this.
|
|
54296
|
+
return this.getVisibleSheetIds().length > 1
|
|
54223
54297
|
? "Success" /* CommandResult.Success */
|
|
54224
54298
|
: "NotEnoughSheets" /* CommandResult.NotEnoughSheets */;
|
|
54225
54299
|
case "ADD_COLUMNS_ROWS":
|
|
@@ -55014,6 +55088,10 @@ class SheetPlugin extends CorePlugin {
|
|
|
55014
55088
|
checkZonesAreInSheet(cmd) {
|
|
55015
55089
|
if (!("sheetId" in cmd))
|
|
55016
55090
|
return "Success" /* CommandResult.Success */;
|
|
55091
|
+
if ("ranges" in cmd &&
|
|
55092
|
+
cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
55093
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
55094
|
+
}
|
|
55017
55095
|
return this.checkZonesExistInSheet(cmd.sheetId, this.getCommandZones(cmd));
|
|
55018
55096
|
}
|
|
55019
55097
|
}
|
|
@@ -55021,6 +55099,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
55021
55099
|
class TablePlugin extends CorePlugin {
|
|
55022
55100
|
static getters = ["getCoreTable", "getCoreTables", "getCoreTableMatchingTopLeft"];
|
|
55023
55101
|
tables = {};
|
|
55102
|
+
insertionOrders = {};
|
|
55024
55103
|
adaptRanges(applyChange, sheetId) {
|
|
55025
55104
|
const sheetIds = sheetId ? [sheetId] : this.getters.getSheetIds();
|
|
55026
55105
|
for (const sheetId of sheetIds) {
|
|
@@ -55032,6 +55111,9 @@ class TablePlugin extends CorePlugin {
|
|
|
55032
55111
|
allowDispatch(cmd) {
|
|
55033
55112
|
switch (cmd.type) {
|
|
55034
55113
|
case "CREATE_TABLE":
|
|
55114
|
+
if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId) || rangeData._sheetId !== cmd.sheetId)) {
|
|
55115
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
55116
|
+
}
|
|
55035
55117
|
const zones = cmd.ranges.map((rangeData) => this.getters.getRangeFromRangeData(rangeData).zone);
|
|
55036
55118
|
if (!areZonesContinuous(zones)) {
|
|
55037
55119
|
return "NonContinuousTargets" /* CommandResult.NonContinuousTargets */;
|
|
@@ -55062,11 +55144,13 @@ class TablePlugin extends CorePlugin {
|
|
|
55062
55144
|
switch (cmd.type) {
|
|
55063
55145
|
case "CREATE_SHEET":
|
|
55064
55146
|
this.history.update("tables", cmd.sheetId, {});
|
|
55147
|
+
this.history.update("insertionOrders", cmd.sheetId, []);
|
|
55065
55148
|
break;
|
|
55066
55149
|
case "DELETE_SHEET": {
|
|
55067
55150
|
const tables = { ...this.tables };
|
|
55068
55151
|
delete tables[cmd.sheetId];
|
|
55069
55152
|
this.history.update("tables", tables);
|
|
55153
|
+
this.history.update("insertionOrders", cmd.sheetId, undefined);
|
|
55070
55154
|
break;
|
|
55071
55155
|
}
|
|
55072
55156
|
case "DUPLICATE_SHEET": {
|
|
@@ -55078,6 +55162,9 @@ class TablePlugin extends CorePlugin {
|
|
|
55078
55162
|
: this.copyStaticTableForSheet(cmd.sheetIdTo, table);
|
|
55079
55163
|
}
|
|
55080
55164
|
this.history.update("tables", cmd.sheetIdTo, newTables);
|
|
55165
|
+
this.history.update("insertionOrders", cmd.sheetIdTo, [
|
|
55166
|
+
...(this.insertionOrders[cmd.sheetId] ?? []),
|
|
55167
|
+
]);
|
|
55081
55168
|
break;
|
|
55082
55169
|
}
|
|
55083
55170
|
case "CREATE_TABLE": {
|
|
@@ -55085,12 +55172,16 @@ class TablePlugin extends CorePlugin {
|
|
|
55085
55172
|
const union = this.getters.getRangesUnion(ranges);
|
|
55086
55173
|
const mergesInTarget = this.getters.getMergesInZone(cmd.sheetId, union.zone);
|
|
55087
55174
|
this.dispatch("REMOVE_MERGE", { sheetId: cmd.sheetId, target: mergesInTarget });
|
|
55088
|
-
const id = this.uuidGenerator.
|
|
55175
|
+
const id = this.uuidGenerator.smallUuid();
|
|
55089
55176
|
const config = cmd.config || DEFAULT_TABLE_CONFIG;
|
|
55090
55177
|
const newTable = cmd.tableType === "dynamic"
|
|
55091
55178
|
? this.createDynamicTable(id, union, config)
|
|
55092
55179
|
: this.createStaticTable(id, cmd.tableType, union, config);
|
|
55093
55180
|
this.history.update("tables", cmd.sheetId, newTable.id, newTable);
|
|
55181
|
+
this.history.update("insertionOrders", cmd.sheetId, [
|
|
55182
|
+
...(this.insertionOrders[cmd.sheetId] ?? []),
|
|
55183
|
+
newTable.id,
|
|
55184
|
+
]);
|
|
55094
55185
|
break;
|
|
55095
55186
|
}
|
|
55096
55187
|
case "REMOVE_TABLE": {
|
|
@@ -55101,6 +55192,7 @@ class TablePlugin extends CorePlugin {
|
|
|
55101
55192
|
}
|
|
55102
55193
|
}
|
|
55103
55194
|
this.history.update("tables", cmd.sheetId, tables);
|
|
55195
|
+
this.history.update("insertionOrders", cmd.sheetId, this.insertionOrders[cmd.sheetId]?.filter((id) => id in tables));
|
|
55104
55196
|
break;
|
|
55105
55197
|
}
|
|
55106
55198
|
case "UPDATE_TABLE": {
|
|
@@ -55136,7 +55228,14 @@ class TablePlugin extends CorePlugin {
|
|
|
55136
55228
|
}
|
|
55137
55229
|
}
|
|
55138
55230
|
getCoreTables(sheetId) {
|
|
55139
|
-
|
|
55231
|
+
const tables = [];
|
|
55232
|
+
for (const tableId of this.insertionOrders[sheetId] || []) {
|
|
55233
|
+
const table = this.tables[sheetId][tableId];
|
|
55234
|
+
if (table) {
|
|
55235
|
+
tables.push(table);
|
|
55236
|
+
}
|
|
55237
|
+
}
|
|
55238
|
+
return tables;
|
|
55140
55239
|
}
|
|
55141
55240
|
getCoreTable({ sheetId, col, row }) {
|
|
55142
55241
|
return this.getCoreTables(sheetId).find((table) => isInside(col, row, table.range.zone));
|
|
@@ -55238,7 +55337,7 @@ class TablePlugin extends CorePlugin {
|
|
|
55238
55337
|
filters = [];
|
|
55239
55338
|
for (const i of range(zone.left, zone.right + 1)) {
|
|
55240
55339
|
const filterZone = { ...zone, left: i, right: i };
|
|
55241
|
-
const uid = this.uuidGenerator.
|
|
55340
|
+
const uid = this.uuidGenerator.smallUuid();
|
|
55242
55341
|
filters.push(this.createFilterFromZone(uid, tableRange.sheetId, filterZone, config));
|
|
55243
55342
|
}
|
|
55244
55343
|
}
|
|
@@ -55303,7 +55402,7 @@ class TablePlugin extends CorePlugin {
|
|
|
55303
55402
|
? table.filters.find((f) => f.col === i)
|
|
55304
55403
|
: undefined;
|
|
55305
55404
|
const filterZone = { ...tableZone, left: i, right: i };
|
|
55306
|
-
const filterId = oldFilter?.id || this.uuidGenerator.
|
|
55405
|
+
const filterId = oldFilter?.id || this.uuidGenerator.smallUuid();
|
|
55307
55406
|
filters.push(this.createFilterFromZone(filterId, tableRange.sheetId, filterZone, config));
|
|
55308
55407
|
}
|
|
55309
55408
|
}
|
|
@@ -55404,7 +55503,7 @@ class TablePlugin extends CorePlugin {
|
|
|
55404
55503
|
if (filters.length < zoneToDimension(tableZone).numberOfCols) {
|
|
55405
55504
|
for (let col = tableZone.left; col <= tableZone.right; col++) {
|
|
55406
55505
|
if (!filters.find((filter) => filter.col === col)) {
|
|
55407
|
-
const uid = this.uuidGenerator.
|
|
55506
|
+
const uid = this.uuidGenerator.smallUuid();
|
|
55408
55507
|
const filterZone = { ...tableZone, left: col, right: col };
|
|
55409
55508
|
filters.push(this.createFilterFromZone(uid, sheetId, filterZone, table.config));
|
|
55410
55509
|
}
|
|
@@ -55419,6 +55518,7 @@ class TablePlugin extends CorePlugin {
|
|
|
55419
55518
|
// ---------------------------------------------------------------------------
|
|
55420
55519
|
import(data) {
|
|
55421
55520
|
for (const sheet of data.sheets) {
|
|
55521
|
+
const tableIds = [];
|
|
55422
55522
|
for (const tableData of sheet.tables || []) {
|
|
55423
55523
|
const uuid = this.uuidGenerator.uuidv4();
|
|
55424
55524
|
const tableConfig = tableData.config || DEFAULT_TABLE_CONFIG;
|
|
@@ -55428,7 +55528,9 @@ class TablePlugin extends CorePlugin {
|
|
|
55428
55528
|
? this.createDynamicTable(uuid, range, tableConfig)
|
|
55429
55529
|
: this.createStaticTable(uuid, tableType, range, tableConfig);
|
|
55430
55530
|
this.history.update("tables", sheet.id, table.id, table);
|
|
55531
|
+
tableIds.push(table.id);
|
|
55431
55532
|
}
|
|
55533
|
+
this.history.update("insertionOrders", sheet.id, tableIds);
|
|
55432
55534
|
}
|
|
55433
55535
|
}
|
|
55434
55536
|
export(data) {
|
|
@@ -55468,7 +55570,10 @@ class HeaderGroupingPlugin extends CorePlugin {
|
|
|
55468
55570
|
allowDispatch(cmd) {
|
|
55469
55571
|
switch (cmd.type) {
|
|
55470
55572
|
case "GROUP_HEADERS": {
|
|
55471
|
-
const { start, end } = cmd;
|
|
55573
|
+
const { start, end, sheetId } = cmd;
|
|
55574
|
+
if (!this.getters.tryGetSheet(sheetId)) {
|
|
55575
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
55576
|
+
}
|
|
55472
55577
|
if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
|
|
55473
55578
|
return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
|
|
55474
55579
|
}
|
|
@@ -55481,7 +55586,10 @@ class HeaderGroupingPlugin extends CorePlugin {
|
|
|
55481
55586
|
break;
|
|
55482
55587
|
}
|
|
55483
55588
|
case "UNGROUP_HEADERS": {
|
|
55484
|
-
const { start, end } = cmd;
|
|
55589
|
+
const { start, end, sheetId } = cmd;
|
|
55590
|
+
if (!this.getters.tryGetSheet(sheetId)) {
|
|
55591
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
55592
|
+
}
|
|
55485
55593
|
if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
|
|
55486
55594
|
return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
|
|
55487
55595
|
}
|
|
@@ -55492,6 +55600,9 @@ class HeaderGroupingPlugin extends CorePlugin {
|
|
|
55492
55600
|
}
|
|
55493
55601
|
case "UNFOLD_HEADER_GROUP":
|
|
55494
55602
|
case "FOLD_HEADER_GROUP":
|
|
55603
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
55604
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
55605
|
+
}
|
|
55495
55606
|
const group = this.findGroupWithStartEnd(cmd.sheetId, cmd.dimension, cmd.start, cmd.end);
|
|
55496
55607
|
if (!group) {
|
|
55497
55608
|
return "UnknownHeaderGroup" /* CommandResult.UnknownHeaderGroup */;
|
|
@@ -55892,6 +56003,9 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
55892
56003
|
return this.checkDuplicatedMeasureIds(cmd.pivot);
|
|
55893
56004
|
}
|
|
55894
56005
|
case "UPDATE_PIVOT": {
|
|
56006
|
+
if (!(cmd.pivotId in this.pivots)) {
|
|
56007
|
+
return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
|
|
56008
|
+
}
|
|
55895
56009
|
if (deepEquals(cmd.pivot, this.pivots[cmd.pivotId]?.definition)) {
|
|
55896
56010
|
return "NoChanges" /* CommandResult.NoChanges */;
|
|
55897
56011
|
}
|
|
@@ -55908,6 +56022,8 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
55908
56022
|
return "EmptyName" /* CommandResult.EmptyName */;
|
|
55909
56023
|
}
|
|
55910
56024
|
break;
|
|
56025
|
+
case "REMOVE_PIVOT":
|
|
56026
|
+
case "DUPLICATE_PIVOT":
|
|
55911
56027
|
case "INSERT_PIVOT": {
|
|
55912
56028
|
if (!(cmd.pivotId in this.pivots)) {
|
|
55913
56029
|
return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
|
|
@@ -55957,7 +56073,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
55957
56073
|
break;
|
|
55958
56074
|
}
|
|
55959
56075
|
case "UPDATE_PIVOT": {
|
|
55960
|
-
this.history.update("pivots", cmd.pivotId, "definition", cmd.pivot);
|
|
56076
|
+
this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
|
|
55961
56077
|
this.compileCalculatedMeasures(cmd.pivot.measures);
|
|
55962
56078
|
break;
|
|
55963
56079
|
}
|
|
@@ -56028,7 +56144,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
56028
56144
|
// Private
|
|
56029
56145
|
// -------------------------------------------------------------------------
|
|
56030
56146
|
addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
|
|
56031
|
-
this.history.update("pivots", pivotId, { definition: pivot, formulaId });
|
|
56147
|
+
this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
|
|
56032
56148
|
this.compileCalculatedMeasures(pivot.measures);
|
|
56033
56149
|
this.history.update("formulaIds", formulaId, pivotId);
|
|
56034
56150
|
this.history.update("nextFormulaId", this.nextFormulaId + 1);
|
|
@@ -60960,6 +61076,9 @@ function updateChartRangesTransformation(toTransform, executed) {
|
|
|
60960
61076
|
};
|
|
60961
61077
|
}
|
|
60962
61078
|
function createSheetTransformation(toTransform, executed) {
|
|
61079
|
+
if (toTransform.sheetId === executed.sheetId) {
|
|
61080
|
+
toTransform = { ...toTransform, sheetId: `${toTransform.sheetId}~` };
|
|
61081
|
+
}
|
|
60963
61082
|
if (toTransform.name === executed.name) {
|
|
60964
61083
|
return {
|
|
60965
61084
|
...toTransform,
|
|
@@ -61612,21 +61731,14 @@ class Session extends EventBus {
|
|
|
61612
61731
|
if (!message)
|
|
61613
61732
|
return;
|
|
61614
61733
|
if (message.type === "REMOTE_REVISION") {
|
|
61615
|
-
|
|
61734
|
+
let revision = this.revisions.get(message.nextRevisionId);
|
|
61616
61735
|
if (revision.commands.length === 0) {
|
|
61617
61736
|
/**
|
|
61618
|
-
* The command is empty, we have to
|
|
61737
|
+
* The command is empty, we have to rebase all the next local revisions
|
|
61619
61738
|
* to avoid issues with undo/redo
|
|
61620
61739
|
*/
|
|
61621
|
-
this.revisions.
|
|
61622
|
-
|
|
61623
|
-
.filter((message) => message.type === "REMOTE_REVISION")
|
|
61624
|
-
.map((message) => message.nextRevisionId);
|
|
61625
|
-
this.trigger("pending-revisions-dropped", { revisionIds });
|
|
61626
|
-
this.waitingAck = false;
|
|
61627
|
-
this.waitingUndoRedoAck = false;
|
|
61628
|
-
this.pendingMessages = [];
|
|
61629
|
-
return;
|
|
61740
|
+
this.revisions.rebase(revision.id);
|
|
61741
|
+
revision = this.revisions.get(message.nextRevisionId);
|
|
61630
61742
|
}
|
|
61631
61743
|
message = {
|
|
61632
61744
|
...message,
|
|
@@ -61650,7 +61762,6 @@ class Session extends EventBus {
|
|
|
61650
61762
|
switch (message.type) {
|
|
61651
61763
|
case "REMOTE_REVISION":
|
|
61652
61764
|
case "REVISION_REDONE":
|
|
61653
|
-
case "REVISION_UNDONE":
|
|
61654
61765
|
case "SNAPSHOT_CREATED":
|
|
61655
61766
|
this.waitingAck = false;
|
|
61656
61767
|
this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
|
|
@@ -61659,6 +61770,25 @@ class Session extends EventBus {
|
|
|
61659
61770
|
this.lastRevisionMessage = message;
|
|
61660
61771
|
this.sendPendingMessage();
|
|
61661
61772
|
break;
|
|
61773
|
+
case "REVISION_UNDONE": {
|
|
61774
|
+
this.waitingAck = false;
|
|
61775
|
+
this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
|
|
61776
|
+
const firstPendingRevisionId = this.pendingMessages.findIndex((message) => message.type === "REMOTE_REVISION");
|
|
61777
|
+
if (firstPendingRevisionId !== -1) {
|
|
61778
|
+
/**
|
|
61779
|
+
* Some revisions undergo transformations that may cause issues with
|
|
61780
|
+
* undo/redo if the transformation is destructive (we don't get back
|
|
61781
|
+
* the original command by transforming it with the inverse).
|
|
61782
|
+
* To prevent these problems, we must rebase all subsequent local
|
|
61783
|
+
* revisions.
|
|
61784
|
+
*/
|
|
61785
|
+
this.revisions.rebase(this.pendingMessages[firstPendingRevisionId].nextRevisionId);
|
|
61786
|
+
}
|
|
61787
|
+
this.serverRevisionId = message.nextRevisionId;
|
|
61788
|
+
this.processedRevisions.add(message.nextRevisionId);
|
|
61789
|
+
this.sendPendingMessage();
|
|
61790
|
+
break;
|
|
61791
|
+
}
|
|
61662
61792
|
}
|
|
61663
61793
|
}
|
|
61664
61794
|
isAlreadyProcessed(message) {
|
|
@@ -62741,6 +62871,10 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
62741
62871
|
*/
|
|
62742
62872
|
checkZonesAreInSheet(cmd) {
|
|
62743
62873
|
const sheetId = "sheetId" in cmd ? cmd.sheetId : this.getters.tryGetActiveSheetId();
|
|
62874
|
+
if ("ranges" in cmd &&
|
|
62875
|
+
cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
62876
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
62877
|
+
}
|
|
62744
62878
|
const zones = this.getters.getCommandZones(cmd);
|
|
62745
62879
|
if (!sheetId && zones.length > 0) {
|
|
62746
62880
|
return "NoActiveSheet" /* CommandResult.NoActiveSheet */;
|
|
@@ -63090,23 +63224,23 @@ const uuidGenerator = new UuidGenerator();
|
|
|
63090
63224
|
function repeatCreateChartCommand(getters, cmd) {
|
|
63091
63225
|
return {
|
|
63092
63226
|
...repeatSheetDependantCommand(getters, cmd),
|
|
63093
|
-
id: uuidGenerator.
|
|
63227
|
+
id: uuidGenerator.smallUuid(),
|
|
63094
63228
|
};
|
|
63095
63229
|
}
|
|
63096
63230
|
function repeatCreateImageCommand(getters, cmd) {
|
|
63097
63231
|
return {
|
|
63098
63232
|
...repeatSheetDependantCommand(getters, cmd),
|
|
63099
|
-
figureId: uuidGenerator.
|
|
63233
|
+
figureId: uuidGenerator.smallUuid(),
|
|
63100
63234
|
};
|
|
63101
63235
|
}
|
|
63102
63236
|
function repeatCreateFigureCommand(getters, cmd) {
|
|
63103
63237
|
const newCmd = repeatSheetDependantCommand(getters, cmd);
|
|
63104
|
-
newCmd.figure.id = uuidGenerator.
|
|
63238
|
+
newCmd.figure.id = uuidGenerator.smallUuid();
|
|
63105
63239
|
return newCmd;
|
|
63106
63240
|
}
|
|
63107
63241
|
function repeatCreateSheetCommand(getters, cmd) {
|
|
63108
63242
|
const newCmd = deepCopy(cmd);
|
|
63109
|
-
newCmd.sheetId = uuidGenerator.
|
|
63243
|
+
newCmd.sheetId = uuidGenerator.smallUuid();
|
|
63110
63244
|
const sheetName = cmd.name || getters.getSheet(getters.getActiveSheetId()).name;
|
|
63111
63245
|
// Extract the prefix of the sheet name (everything before the number at the end of the name)
|
|
63112
63246
|
const namePrefix = sheetName.match(/(.+?)\d*$/)?.[1] || sheetName;
|
|
@@ -63295,7 +63429,6 @@ class HistoryPlugin extends UIPlugin {
|
|
|
63295
63429
|
super(config);
|
|
63296
63430
|
this.session = config.session;
|
|
63297
63431
|
this.session.on("new-local-state-update", this, this.onNewLocalStateUpdate);
|
|
63298
|
-
this.session.on("pending-revisions-dropped", this, ({ revisionIds }) => this.drop(revisionIds));
|
|
63299
63432
|
this.session.on("snapshot", this, () => {
|
|
63300
63433
|
this.undoStack = [];
|
|
63301
63434
|
this.redoStack = [];
|
|
@@ -63365,10 +63498,6 @@ class HistoryPlugin extends UIPlugin {
|
|
|
63365
63498
|
const lastNonRedoRevision = this.getPossibleRevisionToRepeat();
|
|
63366
63499
|
return canRepeatRevision(lastNonRedoRevision);
|
|
63367
63500
|
}
|
|
63368
|
-
drop(revisionIds) {
|
|
63369
|
-
this.undoStack = this.undoStack.filter((id) => !revisionIds.includes(id));
|
|
63370
|
-
this.redoStack = [];
|
|
63371
|
-
}
|
|
63372
63501
|
onNewLocalStateUpdate({ id }) {
|
|
63373
63502
|
this.undoStack.push(id);
|
|
63374
63503
|
this.redoStack = [];
|
|
@@ -64569,23 +64698,7 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
64569
64698
|
gridSelection: deepCopy(gridSelection),
|
|
64570
64699
|
};
|
|
64571
64700
|
}
|
|
64572
|
-
|
|
64573
|
-
const currentSheetIds = this.getters.getVisibleSheetIds();
|
|
64574
|
-
this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
|
|
64575
|
-
if (this.activeSheet.id in this.sheetsData) {
|
|
64576
|
-
const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
|
|
64577
|
-
this.selectCell(anchor.cell.col, anchor.cell.row);
|
|
64578
|
-
}
|
|
64579
|
-
else {
|
|
64580
|
-
this.selectCell(0, 0);
|
|
64581
|
-
}
|
|
64582
|
-
const { col, row } = this.gridSelection.anchor.cell;
|
|
64583
|
-
this.moveClient({
|
|
64584
|
-
sheetId: this.getters.getActiveSheetId(),
|
|
64585
|
-
col,
|
|
64586
|
-
row,
|
|
64587
|
-
});
|
|
64588
|
-
}
|
|
64701
|
+
this.fallbackToVisibleSheet();
|
|
64589
64702
|
const sheetId = this.getters.getActiveSheetId();
|
|
64590
64703
|
this.gridSelection.zones = this.gridSelection.zones.map((z) => this.getters.expandZone(sheetId, z));
|
|
64591
64704
|
this.gridSelection.anchor.zone = this.getters.expandZone(sheetId, this.gridSelection.anchor.zone);
|
|
@@ -64595,6 +64708,7 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
64595
64708
|
}
|
|
64596
64709
|
}
|
|
64597
64710
|
finalize() {
|
|
64711
|
+
this.fallbackToVisibleSheet();
|
|
64598
64712
|
/** Any change to the selection has to be reflected in the selection processor. */
|
|
64599
64713
|
this.selection.resetDefaultAnchor(this, deepCopy(this.gridSelection.anchor));
|
|
64600
64714
|
}
|
|
@@ -64898,6 +65012,25 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
64898
65012
|
}
|
|
64899
65013
|
return "Success" /* CommandResult.Success */;
|
|
64900
65014
|
}
|
|
65015
|
+
fallbackToVisibleSheet() {
|
|
65016
|
+
if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
|
|
65017
|
+
const currentSheetIds = this.getters.getVisibleSheetIds();
|
|
65018
|
+
this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
|
|
65019
|
+
if (this.activeSheet.id in this.sheetsData) {
|
|
65020
|
+
const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
|
|
65021
|
+
this.selectCell(anchor.cell.col, anchor.cell.row);
|
|
65022
|
+
}
|
|
65023
|
+
else {
|
|
65024
|
+
this.selectCell(0, 0);
|
|
65025
|
+
}
|
|
65026
|
+
const { col, row } = this.gridSelection.anchor.cell;
|
|
65027
|
+
this.moveClient({
|
|
65028
|
+
sheetId: this.getters.getActiveSheetId(),
|
|
65029
|
+
col,
|
|
65030
|
+
row,
|
|
65031
|
+
});
|
|
65032
|
+
}
|
|
65033
|
+
}
|
|
64901
65034
|
//-------------------------------------------
|
|
64902
65035
|
// Helpers for extensions
|
|
64903
65036
|
// ------------------------------------------
|
|
@@ -66064,7 +66197,9 @@ class HeaderPositionsUIPlugin extends UIPlugin {
|
|
|
66064
66197
|
case "UNGROUP_HEADERS":
|
|
66065
66198
|
case "GROUP_HEADERS":
|
|
66066
66199
|
case "CREATE_SHEET":
|
|
66067
|
-
this.
|
|
66200
|
+
if (this.getters.tryGetSheet(cmd.sheetId)) {
|
|
66201
|
+
this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
|
|
66202
|
+
}
|
|
66068
66203
|
break;
|
|
66069
66204
|
case "DUPLICATE_SHEET":
|
|
66070
66205
|
this.headerPositions[cmd.sheetIdTo] = deepCopy(this.headerPositions[cmd.sheetId]);
|
|
@@ -66072,12 +66207,14 @@ class HeaderPositionsUIPlugin extends UIPlugin {
|
|
|
66072
66207
|
}
|
|
66073
66208
|
}
|
|
66074
66209
|
finalize() {
|
|
66075
|
-
|
|
66076
|
-
|
|
66210
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
66211
|
+
// sheets can be created without this plugin being aware of it
|
|
66212
|
+
// in concurrent situations.
|
|
66213
|
+
if (this.isDirty || !this.headerPositions[sheetId]) {
|
|
66077
66214
|
this.headerPositions[sheetId] = this.computeHeaderPositionsOfSheet(sheetId);
|
|
66078
66215
|
}
|
|
66079
|
-
this.isDirty = false;
|
|
66080
66216
|
}
|
|
66217
|
+
this.isDirty = false;
|
|
66081
66218
|
}
|
|
66082
66219
|
/**
|
|
66083
66220
|
* Returns the size, start and end coordinates of a column on an unfolded sheet
|
|
@@ -66900,7 +67037,7 @@ class BottomBar extends owl.Component {
|
|
|
66900
67037
|
clickAddSheet(ev) {
|
|
66901
67038
|
const activeSheetId = this.env.model.getters.getActiveSheetId();
|
|
66902
67039
|
const position = this.env.model.getters.getSheetIds().findIndex((sheetId) => sheetId === activeSheetId) + 1;
|
|
66903
|
-
const sheetId = this.env.model.uuidGenerator.
|
|
67040
|
+
const sheetId = this.env.model.uuidGenerator.smallUuid();
|
|
66904
67041
|
const name = this.env.model.getters.getNextSheetName(_t("Sheet"));
|
|
66905
67042
|
this.env.model.dispatch("CREATE_SHEET", { sheetId, position, name });
|
|
66906
67043
|
this.env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
|
|
@@ -67988,7 +68125,7 @@ css /* scss */ `
|
|
|
67988
68125
|
.o-font-size-editor {
|
|
67989
68126
|
height: calc(100% - 4px);
|
|
67990
68127
|
input.o-font-size {
|
|
67991
|
-
outline
|
|
68128
|
+
outline: none;
|
|
67992
68129
|
height: 20px;
|
|
67993
68130
|
width: 23px;
|
|
67994
68131
|
}
|
|
@@ -69275,7 +69412,7 @@ class Tree {
|
|
|
69275
69412
|
}
|
|
69276
69413
|
/**
|
|
69277
69414
|
* Drop the operation and all following operations in every
|
|
69278
|
-
*
|
|
69415
|
+
* branches
|
|
69279
69416
|
*/
|
|
69280
69417
|
drop(operationId) {
|
|
69281
69418
|
for (const branch of this.branches) {
|
|
@@ -69580,9 +69717,16 @@ class SelectiveHistory {
|
|
|
69580
69717
|
this.fastForward();
|
|
69581
69718
|
this.insert(redoId, this.buildEmpty(redoId), insertAfter);
|
|
69582
69719
|
}
|
|
69583
|
-
|
|
69720
|
+
rebase(operationId) {
|
|
69721
|
+
const operation = this.get(operationId);
|
|
69722
|
+
const execution = [...this.tree.execution(this.HEAD_BRANCH).startAfter(operationId)];
|
|
69584
69723
|
this.revertBefore(operationId);
|
|
69724
|
+
const baseId = this.HEAD_OPERATION.id;
|
|
69585
69725
|
this.tree.drop(operationId);
|
|
69726
|
+
this.insert(operationId, operation, baseId);
|
|
69727
|
+
for (const { operation } of execution) {
|
|
69728
|
+
this.insert(operation.id, operation.data, this.HEAD_OPERATION.id);
|
|
69729
|
+
}
|
|
69586
69730
|
}
|
|
69587
69731
|
/**
|
|
69588
69732
|
* Revert the state as it was *before* the given operation was executed.
|
|
@@ -72624,6 +72768,11 @@ class Model extends EventBus {
|
|
|
72624
72768
|
dispatch: (command) => {
|
|
72625
72769
|
const result = this.checkDispatchAllowed(command);
|
|
72626
72770
|
if (!result.isSuccessful) {
|
|
72771
|
+
// core views plugins need to be invalidated
|
|
72772
|
+
this.dispatchToHandlers(this.coreHandlers, {
|
|
72773
|
+
type: "UNDO",
|
|
72774
|
+
commands: [command],
|
|
72775
|
+
});
|
|
72627
72776
|
return;
|
|
72628
72777
|
}
|
|
72629
72778
|
this.isReplayingCommand = true;
|
|
@@ -72652,7 +72801,7 @@ class Model extends EventBus {
|
|
|
72652
72801
|
}
|
|
72653
72802
|
setupConfig(config) {
|
|
72654
72803
|
const client = config.client || {
|
|
72655
|
-
id: this.uuidGenerator.
|
|
72804
|
+
id: this.uuidGenerator.smallUuid(),
|
|
72656
72805
|
name: _t("Anonymous").toString(),
|
|
72657
72806
|
};
|
|
72658
72807
|
const transportService = config.transportService || new LocalTransportService();
|
|
@@ -73182,6 +73331,6 @@ exports.tokenColors = tokenColors;
|
|
|
73182
73331
|
exports.tokenize = tokenize;
|
|
73183
73332
|
|
|
73184
73333
|
|
|
73185
|
-
__info__.version = "18.0.
|
|
73186
|
-
__info__.date = "2025-02-
|
|
73187
|
-
__info__.hash = "
|
|
73334
|
+
__info__.version = "18.0.17";
|
|
73335
|
+
__info__.date = "2025-02-25T05:58:39.632Z";
|
|
73336
|
+
__info__.hash = "2ee4347";
|