@odoo/o-spreadsheet 17.0.48 → 17.0.50
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 +267 -134
- package/dist/o-spreadsheet.d.ts +21 -8
- package/dist/o-spreadsheet.esm.js +267 -134
- package/dist/o-spreadsheet.iife.js +267 -134
- package/dist/o-spreadsheet.iife.min.js +249 -249
- package/dist/o_spreadsheet.xml +4 -3
- package/package.json +2 -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 17.0.
|
|
6
|
-
* @date 2025-02-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.0.50
|
|
6
|
+
* @date 2025-02-14T08:37:34.289Z
|
|
7
|
+
* @hash cc1037d
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -688,9 +688,16 @@ function deepEquals(o1, o2) {
|
|
|
688
688
|
}
|
|
689
689
|
return true;
|
|
690
690
|
}
|
|
691
|
-
/**
|
|
691
|
+
/**
|
|
692
|
+
* Check if the given array contains all the values of the other array.
|
|
693
|
+
* It makes the assumption that both array do not contain duplicates.
|
|
694
|
+
*/
|
|
692
695
|
function includesAll(arr, values) {
|
|
693
|
-
|
|
696
|
+
if (arr.length < values.length) {
|
|
697
|
+
return false;
|
|
698
|
+
}
|
|
699
|
+
const set = new Set(arr);
|
|
700
|
+
return values.every((value) => set.has(value));
|
|
694
701
|
}
|
|
695
702
|
/**
|
|
696
703
|
* Return an object with all the keys in the object that have a falsy value removed.
|
|
@@ -1903,12 +1910,12 @@ function isTargetDependent(cmd) {
|
|
|
1903
1910
|
function isRangeDependant(cmd) {
|
|
1904
1911
|
return "ranges" in cmd;
|
|
1905
1912
|
}
|
|
1906
|
-
function isZoneDependent(cmd) {
|
|
1907
|
-
return "zone" in cmd;
|
|
1908
|
-
}
|
|
1909
1913
|
function isPositionDependent(cmd) {
|
|
1910
1914
|
return "col" in cmd && "row" in cmd && "sheetId" in cmd;
|
|
1911
1915
|
}
|
|
1916
|
+
function isZoneDependent(cmd) {
|
|
1917
|
+
return "sheetId" in cmd && "zone" in cmd;
|
|
1918
|
+
}
|
|
1912
1919
|
const invalidateEvaluationCommands = new Set([
|
|
1913
1920
|
"RENAME_SHEET",
|
|
1914
1921
|
"DELETE_SHEET",
|
|
@@ -1918,6 +1925,7 @@ const invalidateEvaluationCommands = new Set([
|
|
|
1918
1925
|
"UNDO",
|
|
1919
1926
|
"REDO",
|
|
1920
1927
|
"ADD_MERGE",
|
|
1928
|
+
"DUPLICATE_SHEET",
|
|
1921
1929
|
"UPDATE_LOCALE",
|
|
1922
1930
|
]);
|
|
1923
1931
|
const invalidateDependenciesCommands = new Set([
|
|
@@ -1926,7 +1934,6 @@ const invalidateDependenciesCommands = new Set([
|
|
|
1926
1934
|
]);
|
|
1927
1935
|
const invalidateCFEvaluationCommands = new Set([
|
|
1928
1936
|
...invalidateEvaluationCommands,
|
|
1929
|
-
"DUPLICATE_SHEET",
|
|
1930
1937
|
"EVALUATE_CELLS",
|
|
1931
1938
|
"ADD_CONDITIONAL_FORMAT",
|
|
1932
1939
|
"REMOVE_CONDITIONAL_FORMAT",
|
|
@@ -2086,6 +2093,7 @@ exports.CommandResult = void 0;
|
|
|
2086
2093
|
CommandResult["InvalidRange"] = "InvalidRange";
|
|
2087
2094
|
CommandResult["InvalidZones"] = "InvalidZones";
|
|
2088
2095
|
CommandResult["InvalidSheetId"] = "InvalidSheetId";
|
|
2096
|
+
CommandResult["InvalidCellId"] = "InvalidCellId";
|
|
2089
2097
|
CommandResult["InvalidFigureId"] = "InvalidFigureId";
|
|
2090
2098
|
CommandResult["InputAlreadyFocused"] = "InputAlreadyFocused";
|
|
2091
2099
|
CommandResult["MaximumRangesReached"] = "MaximumRangesReached";
|
|
@@ -3666,17 +3674,20 @@ function toZoneWithoutBoundaryChanges(xc) {
|
|
|
3666
3674
|
*/
|
|
3667
3675
|
function toUnboundedZone(xc) {
|
|
3668
3676
|
const zone = toZoneWithoutBoundaryChanges(xc);
|
|
3677
|
+
reorderZone(zone);
|
|
3678
|
+
return zone;
|
|
3679
|
+
}
|
|
3680
|
+
function reorderZone(zone) {
|
|
3669
3681
|
if (zone.right !== undefined && zone.right < zone.left) {
|
|
3670
|
-
const
|
|
3682
|
+
const right = zone.left;
|
|
3671
3683
|
zone.left = zone.right;
|
|
3672
|
-
zone.right =
|
|
3684
|
+
zone.right = right;
|
|
3673
3685
|
}
|
|
3674
3686
|
if (zone.bottom !== undefined && zone.bottom < zone.top) {
|
|
3675
|
-
const
|
|
3687
|
+
const bottom = zone.top;
|
|
3676
3688
|
zone.top = zone.bottom;
|
|
3677
|
-
zone.bottom =
|
|
3689
|
+
zone.bottom = bottom;
|
|
3678
3690
|
}
|
|
3679
|
-
return zone;
|
|
3680
3691
|
}
|
|
3681
3692
|
/**
|
|
3682
3693
|
* Convert from a cartesian reference to a Zone.
|
|
@@ -4709,6 +4720,37 @@ class UuidGenerator {
|
|
|
4709
4720
|
setIsFastStrategy(isFast) {
|
|
4710
4721
|
this.isFastIdStrategy = isFast;
|
|
4711
4722
|
}
|
|
4723
|
+
/**
|
|
4724
|
+
* Generates a custom UUID using a simple 26^8 method (8-character alphanumeric string with lowercase letters)
|
|
4725
|
+
* This has a higher chance of collision than a UUIDv4, but not only faster to generate than an UUIDV4,
|
|
4726
|
+
* it also has a smaller size, which is preferable to alleviate the overall data size.
|
|
4727
|
+
*
|
|
4728
|
+
* This method is preferable when generating uuids for the core data (sheetId, figureId, etc)
|
|
4729
|
+
* as they will appear several times in the revisions and local history.
|
|
4730
|
+
*
|
|
4731
|
+
*/
|
|
4732
|
+
smallUuid() {
|
|
4733
|
+
if (this.isFastIdStrategy) {
|
|
4734
|
+
this.fastIdStart++;
|
|
4735
|
+
return String(this.fastIdStart);
|
|
4736
|
+
//@ts-ignore
|
|
4737
|
+
}
|
|
4738
|
+
else if (window.crypto && window.crypto.getRandomValues) {
|
|
4739
|
+
//@ts-ignore
|
|
4740
|
+
return ([1e7] + -1e3).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
|
|
4741
|
+
}
|
|
4742
|
+
else {
|
|
4743
|
+
// mainly for jest and other browsers that do not have the crypto functionality
|
|
4744
|
+
return "xxxxxxxx-xxxx".replace(/[xy]/g, function (c) {
|
|
4745
|
+
var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
|
|
4746
|
+
return v.toString(16);
|
|
4747
|
+
});
|
|
4748
|
+
}
|
|
4749
|
+
}
|
|
4750
|
+
/**
|
|
4751
|
+
* Generates an UUIDV4, has astronomically low chance of collision, but is larger in size than the smallUuid.
|
|
4752
|
+
* This method should be used when you need to avoid collisions at all costs, like the id of a revision.
|
|
4753
|
+
*/
|
|
4712
4754
|
uuidv4() {
|
|
4713
4755
|
if (this.isFastIdStrategy) {
|
|
4714
4756
|
this.fastIdStart++;
|
|
@@ -4722,7 +4764,7 @@ class UuidGenerator {
|
|
|
4722
4764
|
else {
|
|
4723
4765
|
// mainly for jest and other browsers that do not have the crypto functionality
|
|
4724
4766
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
|
|
4725
|
-
var r = (Math.random() * 16) | 0, v = c
|
|
4767
|
+
var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
|
|
4726
4768
|
return v.toString(16);
|
|
4727
4769
|
});
|
|
4728
4770
|
}
|
|
@@ -7935,7 +7977,7 @@ const linkSheet = {
|
|
|
7935
7977
|
const deleteSheet = {
|
|
7936
7978
|
name: _t("Delete"),
|
|
7937
7979
|
isVisible: (env) => {
|
|
7938
|
-
return env.model.getters.
|
|
7980
|
+
return env.model.getters.getVisibleSheetIds().length > 1;
|
|
7939
7981
|
},
|
|
7940
7982
|
execute: (env) => env.askConfirmation(_t("Are you sure you want to delete this sheet?"), () => {
|
|
7941
7983
|
env.model.dispatch("DELETE_SHEET", { sheetId: env.model.getters.getActiveSheetId() });
|
|
@@ -7945,7 +7987,7 @@ const duplicateSheet = {
|
|
|
7945
7987
|
name: _t("Duplicate"),
|
|
7946
7988
|
execute: (env) => {
|
|
7947
7989
|
const sheetIdFrom = env.model.getters.getActiveSheetId();
|
|
7948
|
-
const sheetIdTo = env.model.uuidGenerator.
|
|
7990
|
+
const sheetIdTo = env.model.uuidGenerator.smallUuid();
|
|
7949
7991
|
env.model.dispatch("DUPLICATE_SHEET", {
|
|
7950
7992
|
sheetId: sheetIdFrom,
|
|
7951
7993
|
sheetIdTo,
|
|
@@ -8495,17 +8537,15 @@ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, tr
|
|
|
8495
8537
|
plugins: [],
|
|
8496
8538
|
};
|
|
8497
8539
|
}
|
|
8498
|
-
function getChartLabelFormat(getters, range) {
|
|
8540
|
+
function getChartLabelFormat(getters, range, shouldRemoveFirstLabel) {
|
|
8499
8541
|
if (!range)
|
|
8500
8542
|
return undefined;
|
|
8501
|
-
const { sheetId, zone
|
|
8502
|
-
|
|
8503
|
-
|
|
8504
|
-
|
|
8505
|
-
return format;
|
|
8506
|
-
}
|
|
8543
|
+
const { sheetId, zone } = range;
|
|
8544
|
+
const formats = positions(zone).map((position) => getters.getEvaluatedCell({ sheetId, ...position }).format);
|
|
8545
|
+
if (shouldRemoveFirstLabel) {
|
|
8546
|
+
formats.shift();
|
|
8507
8547
|
}
|
|
8508
|
-
return undefined;
|
|
8548
|
+
return formats.find((format) => format !== undefined);
|
|
8509
8549
|
}
|
|
8510
8550
|
function getChartLabelValues(getters, dataSets, labelRange) {
|
|
8511
8551
|
let labels = { values: [], formattedValues: [] };
|
|
@@ -8786,9 +8826,7 @@ function createBarChartRuntime(chart, getters) {
|
|
|
8786
8826
|
const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
|
|
8787
8827
|
let labels = labelValues.formattedValues;
|
|
8788
8828
|
let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
|
|
8789
|
-
if (chart.dataSetsHaveTitle
|
|
8790
|
-
dataSetsValues[0] &&
|
|
8791
|
-
labels.length > dataSetsValues[0].data.length) {
|
|
8829
|
+
if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
|
|
8792
8830
|
labels.shift();
|
|
8793
8831
|
}
|
|
8794
8832
|
({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
|
|
@@ -9332,8 +9370,8 @@ function fixEmptyLabelsForDateCharts(labels, dataSetsValues) {
|
|
|
9332
9370
|
}
|
|
9333
9371
|
return { labels: newLabels, dataSetsValues: newDatasets };
|
|
9334
9372
|
}
|
|
9335
|
-
function canChartParseLabels(
|
|
9336
|
-
return canBeDateChart(
|
|
9373
|
+
function canChartParseLabels(chart, getters) {
|
|
9374
|
+
return canBeDateChart(chart, getters) || canBeLinearChart(chart, getters);
|
|
9337
9375
|
}
|
|
9338
9376
|
function getChartAxisType(chart, getters) {
|
|
9339
9377
|
if (isDateChart(chart, getters) && isLuxonTimeAdapterInstalled()) {
|
|
@@ -9345,23 +9383,26 @@ function getChartAxisType(chart, getters) {
|
|
|
9345
9383
|
return "category";
|
|
9346
9384
|
}
|
|
9347
9385
|
function isDateChart(chart, getters) {
|
|
9348
|
-
return !chart.labelsAsText && canBeDateChart(chart
|
|
9386
|
+
return !chart.labelsAsText && canBeDateChart(chart, getters);
|
|
9349
9387
|
}
|
|
9350
9388
|
function isLinearChart(chart, getters) {
|
|
9351
|
-
return !chart.labelsAsText && canBeLinearChart(chart
|
|
9389
|
+
return !chart.labelsAsText && canBeLinearChart(chart, getters);
|
|
9352
9390
|
}
|
|
9353
|
-
function canBeDateChart(
|
|
9354
|
-
if (!labelRange || !canBeLinearChart(
|
|
9391
|
+
function canBeDateChart(chart, getters) {
|
|
9392
|
+
if (!chart.labelRange || !canBeLinearChart(chart, getters)) {
|
|
9355
9393
|
return false;
|
|
9356
9394
|
}
|
|
9357
|
-
const labelFormat = getChartLabelFormat(getters, labelRange);
|
|
9395
|
+
const labelFormat = getChartLabelFormat(getters, chart.labelRange, shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle));
|
|
9358
9396
|
return Boolean(labelFormat && timeFormatLuxonCompatible.test(labelFormat));
|
|
9359
9397
|
}
|
|
9360
|
-
function canBeLinearChart(
|
|
9361
|
-
if (!labelRange) {
|
|
9398
|
+
function canBeLinearChart(chart, getters) {
|
|
9399
|
+
if (!chart.labelRange) {
|
|
9362
9400
|
return false;
|
|
9363
9401
|
}
|
|
9364
|
-
const labels = getters.getRangeValues(labelRange);
|
|
9402
|
+
const labels = getters.getRangeValues(chart.labelRange);
|
|
9403
|
+
if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
|
|
9404
|
+
labels.shift();
|
|
9405
|
+
}
|
|
9365
9406
|
if (labels.some((label) => isNaN(Number(label)) && label)) {
|
|
9366
9407
|
return false;
|
|
9367
9408
|
}
|
|
@@ -9435,9 +9476,8 @@ function createLineChartRuntime(chart, getters) {
|
|
|
9435
9476
|
const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
|
|
9436
9477
|
let labels = axisType === "linear" ? labelValues.values : labelValues.formattedValues;
|
|
9437
9478
|
let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
|
|
9438
|
-
|
|
9439
|
-
|
|
9440
|
-
labels.length > dataSetsValues[0].data.length) {
|
|
9479
|
+
const removeFirstLabel = shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle);
|
|
9480
|
+
if (removeFirstLabel) {
|
|
9441
9481
|
labels.shift();
|
|
9442
9482
|
}
|
|
9443
9483
|
({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
|
|
@@ -9452,7 +9492,7 @@ function createLineChartRuntime(chart, getters) {
|
|
|
9452
9492
|
const dataSetFormat = getChartDatasetFormat(getters, chart.dataSets);
|
|
9453
9493
|
const options = { format: dataSetFormat, locale, truncateLabels };
|
|
9454
9494
|
const config = getLineConfiguration(chart, labels, options);
|
|
9455
|
-
const labelFormat = getChartLabelFormat(getters, chart.labelRange);
|
|
9495
|
+
const labelFormat = getChartLabelFormat(getters, chart.labelRange, removeFirstLabel);
|
|
9456
9496
|
if (axisType === "time") {
|
|
9457
9497
|
const axis = {
|
|
9458
9498
|
type: "time",
|
|
@@ -9674,9 +9714,7 @@ function createPieChartRuntime(chart, getters) {
|
|
|
9674
9714
|
const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
|
|
9675
9715
|
let labels = labelValues.formattedValues;
|
|
9676
9716
|
let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
|
|
9677
|
-
if (chart.dataSetsHaveTitle
|
|
9678
|
-
dataSetsValues[0] &&
|
|
9679
|
-
labels.length > dataSetsValues[0].data.length) {
|
|
9717
|
+
if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
|
|
9680
9718
|
labels.shift();
|
|
9681
9719
|
}
|
|
9682
9720
|
({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
|
|
@@ -10197,21 +10235,22 @@ function getSmartChartDefinition(zone, getters) {
|
|
|
10197
10235
|
}
|
|
10198
10236
|
// Only display legend for several datasets.
|
|
10199
10237
|
const newLegendPos = dataSetZone.right === dataSetZone.left ? "none" : "top";
|
|
10200
|
-
const
|
|
10201
|
-
|
|
10202
|
-
|
|
10203
|
-
|
|
10204
|
-
|
|
10205
|
-
|
|
10206
|
-
|
|
10207
|
-
|
|
10208
|
-
|
|
10209
|
-
|
|
10210
|
-
|
|
10211
|
-
|
|
10212
|
-
|
|
10213
|
-
|
|
10214
|
-
|
|
10238
|
+
const lineChartDefinition = {
|
|
10239
|
+
title,
|
|
10240
|
+
dataSets,
|
|
10241
|
+
labelsAsText: false,
|
|
10242
|
+
stacked: false,
|
|
10243
|
+
aggregated: false,
|
|
10244
|
+
cumulative: false,
|
|
10245
|
+
labelRange: labelRangeXc,
|
|
10246
|
+
type: "line",
|
|
10247
|
+
dataSetsHaveTitle,
|
|
10248
|
+
verticalAxisPosition: "left",
|
|
10249
|
+
legendPosition: newLegendPos,
|
|
10250
|
+
};
|
|
10251
|
+
const chart = new LineChart(lineChartDefinition, sheetId, getters);
|
|
10252
|
+
if (canChartParseLabels(chart, getters)) {
|
|
10253
|
+
return lineChartDefinition;
|
|
10215
10254
|
}
|
|
10216
10255
|
return {
|
|
10217
10256
|
title,
|
|
@@ -10811,7 +10850,7 @@ const HIDE_ROWS_NAME = (env) => {
|
|
|
10811
10850
|
//------------------------------------------------------------------------------
|
|
10812
10851
|
const CREATE_CHART = (env) => {
|
|
10813
10852
|
const getters = env.model.getters;
|
|
10814
|
-
const id = env.model.uuidGenerator.
|
|
10853
|
+
const id = env.model.uuidGenerator.smallUuid();
|
|
10815
10854
|
const sheetId = getters.getActiveSheetId();
|
|
10816
10855
|
if (getZoneArea(env.model.getters.getSelectedZone()) === 1) {
|
|
10817
10856
|
env.model.selection.selectTableAroundSelection();
|
|
@@ -10845,7 +10884,7 @@ async function requestImage(env) {
|
|
|
10845
10884
|
const CREATE_IMAGE = async (env) => {
|
|
10846
10885
|
if (env.imageProvider) {
|
|
10847
10886
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
10848
|
-
const figureId = env.model.uuidGenerator.
|
|
10887
|
+
const figureId = env.model.uuidGenerator.smallUuid();
|
|
10849
10888
|
const image = await requestImage(env);
|
|
10850
10889
|
if (!image) {
|
|
10851
10890
|
throw new Error("No image provider was given to the environment");
|
|
@@ -12566,6 +12605,26 @@ const LN = {
|
|
|
12566
12605
|
isExported: true,
|
|
12567
12606
|
};
|
|
12568
12607
|
// -----------------------------------------------------------------------------
|
|
12608
|
+
// LOG
|
|
12609
|
+
// -----------------------------------------------------------------------------
|
|
12610
|
+
const LOG = {
|
|
12611
|
+
description: _t("The logarithm of a number, for a given base."),
|
|
12612
|
+
args: [
|
|
12613
|
+
arg("value (number)", _t("The value for which to calculate the logarithm.")),
|
|
12614
|
+
arg("base (number, default=10)", _t("The base of the logarithm.")),
|
|
12615
|
+
],
|
|
12616
|
+
returns: ["NUMBER"],
|
|
12617
|
+
compute: function (value, base = 10) {
|
|
12618
|
+
const _value = toNumber(value, this.locale);
|
|
12619
|
+
const _base = toNumber(base, this.locale);
|
|
12620
|
+
assert(() => _value > 0, _t("The value (%s) must be strictly positive.", _value.toString()));
|
|
12621
|
+
assert(() => _base > 0, _t("The base (%s) must be strictly positive.", _base.toString()));
|
|
12622
|
+
assert(() => _base !== 1, _t("The base must be different from 1."));
|
|
12623
|
+
return Math.log10(_value) / Math.log10(_base);
|
|
12624
|
+
},
|
|
12625
|
+
isExported: true,
|
|
12626
|
+
};
|
|
12627
|
+
// -----------------------------------------------------------------------------
|
|
12569
12628
|
// MOD
|
|
12570
12629
|
// -----------------------------------------------------------------------------
|
|
12571
12630
|
const MOD = {
|
|
@@ -13086,6 +13145,7 @@ var math = /*#__PURE__*/Object.freeze({
|
|
|
13086
13145
|
ISODD: ISODD,
|
|
13087
13146
|
ISO_CEILING: ISO_CEILING,
|
|
13088
13147
|
LN: LN,
|
|
13148
|
+
LOG: LOG,
|
|
13089
13149
|
MOD: MOD,
|
|
13090
13150
|
MUNIT: MUNIT,
|
|
13091
13151
|
ODD: ODD,
|
|
@@ -15947,7 +16007,7 @@ const SORTN = {
|
|
|
15947
16007
|
}
|
|
15948
16008
|
}
|
|
15949
16009
|
},
|
|
15950
|
-
isExported:
|
|
16010
|
+
isExported: false,
|
|
15951
16011
|
};
|
|
15952
16012
|
// -----------------------------------------------------------------------------
|
|
15953
16013
|
// UNIQUE
|
|
@@ -19848,7 +19908,7 @@ const insertSheet = {
|
|
|
19848
19908
|
execute: (env) => {
|
|
19849
19909
|
const activeSheetId = env.model.getters.getActiveSheetId();
|
|
19850
19910
|
const position = env.model.getters.getSheetIds().indexOf(activeSheetId) + 1;
|
|
19851
|
-
const sheetId = env.model.uuidGenerator.
|
|
19911
|
+
const sheetId = env.model.uuidGenerator.smallUuid();
|
|
19852
19912
|
env.model.dispatch("CREATE_SHEET", { sheetId, position });
|
|
19853
19913
|
env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
|
|
19854
19914
|
},
|
|
@@ -21524,7 +21584,7 @@ css /* scss */ `
|
|
|
21524
21584
|
*/
|
|
21525
21585
|
class SelectionInput extends owl.Component {
|
|
21526
21586
|
static template = "o-spreadsheet-SelectionInput";
|
|
21527
|
-
id = uuidGenerator$1.
|
|
21587
|
+
id = uuidGenerator$1.smallUuid();
|
|
21528
21588
|
previousRanges = this.props.ranges() || [];
|
|
21529
21589
|
originSheet = this.env.model.getters.getActiveSheetId();
|
|
21530
21590
|
state = owl.useState({
|
|
@@ -22574,7 +22634,7 @@ class LineConfigPanel extends LineBarPieConfigPanel {
|
|
|
22574
22634
|
get canTreatLabelsAsText() {
|
|
22575
22635
|
const chart = this.env.model.getters.getChart(this.props.figureId);
|
|
22576
22636
|
if (chart && chart instanceof LineChart) {
|
|
22577
|
-
return canChartParseLabels(chart
|
|
22637
|
+
return canChartParseLabels(chart, this.env.model.getters);
|
|
22578
22638
|
}
|
|
22579
22639
|
return false;
|
|
22580
22640
|
}
|
|
@@ -23602,7 +23662,7 @@ class ConditionalFormattingEditor extends owl.Component {
|
|
|
23602
23662
|
state;
|
|
23603
23663
|
setup() {
|
|
23604
23664
|
const cf = this.props.editedCf || {
|
|
23605
|
-
id: this.env.model.uuidGenerator.
|
|
23665
|
+
id: this.env.model.uuidGenerator.smallUuid(),
|
|
23606
23666
|
ranges: this.env.model.getters
|
|
23607
23667
|
.getSelectedZones()
|
|
23608
23668
|
.map((zone) => this.env.model.getters.zoneToXC(this.env.model.getters.getActiveSheetId(), zone)),
|
|
@@ -25551,7 +25611,7 @@ class DataValidationEditor extends owl.Component {
|
|
|
25551
25611
|
.getSelectedZones()
|
|
25552
25612
|
.map((zone) => zoneToXc(this.env.model.getters.getUnboundedZone(sheetId, zone)));
|
|
25553
25613
|
return {
|
|
25554
|
-
id: this.env.model.uuidGenerator.
|
|
25614
|
+
id: this.env.model.uuidGenerator.smallUuid(),
|
|
25555
25615
|
criterion: { type: "textContains", values: [""] },
|
|
25556
25616
|
ranges,
|
|
25557
25617
|
};
|
|
@@ -34171,7 +34231,7 @@ function forceUnicityOfFigure(data) {
|
|
|
34171
34231
|
for (const sheet of data.sheets || []) {
|
|
34172
34232
|
for (const figure of sheet.figures || []) {
|
|
34173
34233
|
if (figureIds.has(figure.id)) {
|
|
34174
|
-
figure.id += uuidGenerator.
|
|
34234
|
+
figure.id += uuidGenerator.smallUuid();
|
|
34175
34235
|
}
|
|
34176
34236
|
figureIds.add(figure.id);
|
|
34177
34237
|
}
|
|
@@ -35847,6 +35907,10 @@ class CellPlugin extends CorePlugin {
|
|
|
35847
35907
|
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
|
|
35848
35908
|
case "CLEAR_CELL":
|
|
35849
35909
|
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
|
|
35910
|
+
case "UPDATE_CELL_POSITION":
|
|
35911
|
+
return !cmd.cellId || this.cells[cmd.sheetId]?.[cmd.cellId]
|
|
35912
|
+
? "Success" /* CommandResult.Success */
|
|
35913
|
+
: "InvalidCellId" /* CommandResult.InvalidCellId */;
|
|
35850
35914
|
default:
|
|
35851
35915
|
return "Success" /* CommandResult.Success */;
|
|
35852
35916
|
}
|
|
@@ -35888,6 +35952,9 @@ class CellPlugin extends CorePlugin {
|
|
|
35888
35952
|
case "CLEAR_CELLS":
|
|
35889
35953
|
this.clearCells(cmd.sheetId, cmd.target);
|
|
35890
35954
|
break;
|
|
35955
|
+
case "DELETE_SHEET": {
|
|
35956
|
+
this.history.update("cells", cmd.sheetId, undefined);
|
|
35957
|
+
}
|
|
35891
35958
|
}
|
|
35892
35959
|
}
|
|
35893
35960
|
/**
|
|
@@ -36966,8 +37033,14 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
36966
37033
|
allowDispatch(cmd) {
|
|
36967
37034
|
switch (cmd.type) {
|
|
36968
37035
|
case "ADD_DATA_VALIDATION_RULE":
|
|
37036
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
37037
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
37038
|
+
}
|
|
36969
37039
|
return this.checkValidations(cmd, this.chainValidations(this.checkCriterionTypeIsValid, this.checkCriterionHasValidNumberOfValues, this.checkCriterionValuesAreValid));
|
|
36970
37040
|
case "REMOVE_DATA_VALIDATION_RULE":
|
|
37041
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
37042
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
37043
|
+
}
|
|
36971
37044
|
if (!this.rules[cmd.sheetId].find((rule) => rule.id === cmd.id)) {
|
|
36972
37045
|
return "UnknownDataValidationRule" /* CommandResult.UnknownDataValidationRule */;
|
|
36973
37046
|
}
|
|
@@ -37141,6 +37214,7 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
37141
37214
|
class FigurePlugin extends CorePlugin {
|
|
37142
37215
|
static getters = ["getFigures", "getFigure", "getFigureSheetId"];
|
|
37143
37216
|
figures = {};
|
|
37217
|
+
insertionOrders = []; // TODO use a list in master
|
|
37144
37218
|
// ---------------------------------------------------------------------------
|
|
37145
37219
|
// Command Handling
|
|
37146
37220
|
// ---------------------------------------------------------------------------
|
|
@@ -37243,11 +37317,14 @@ class FigurePlugin extends CorePlugin {
|
|
|
37243
37317
|
}
|
|
37244
37318
|
addFigure(figure, sheetId) {
|
|
37245
37319
|
this.history.update("figures", sheetId, figure.id, figure);
|
|
37320
|
+
this.history.update("insertionOrders", this.insertionOrders.length, figure.id);
|
|
37246
37321
|
}
|
|
37247
37322
|
deleteSheet(sheetId) {
|
|
37323
|
+
this.history.update("insertionOrders", this.insertionOrders.filter((id) => !this.figures[sheetId]?.[id]));
|
|
37248
37324
|
this.history.update("figures", sheetId, undefined);
|
|
37249
37325
|
}
|
|
37250
37326
|
removeFigure(id, sheetId) {
|
|
37327
|
+
this.history.update("insertionOrders", this.insertionOrders.filter((figureId) => figureId !== id));
|
|
37251
37328
|
this.history.update("figures", sheetId, id, undefined);
|
|
37252
37329
|
}
|
|
37253
37330
|
checkFigureExists(sheetId, figureId) {
|
|
@@ -37266,7 +37343,14 @@ class FigurePlugin extends CorePlugin {
|
|
|
37266
37343
|
// Getters
|
|
37267
37344
|
// ---------------------------------------------------------------------------
|
|
37268
37345
|
getFigures(sheetId) {
|
|
37269
|
-
|
|
37346
|
+
const figures = [];
|
|
37347
|
+
for (const figureId of this.insertionOrders) {
|
|
37348
|
+
const figure = this.figures[sheetId]?.[figureId];
|
|
37349
|
+
if (figure) {
|
|
37350
|
+
figures.push(figure);
|
|
37351
|
+
}
|
|
37352
|
+
}
|
|
37353
|
+
return figures;
|
|
37270
37354
|
}
|
|
37271
37355
|
getFigure(sheetId, figureId) {
|
|
37272
37356
|
return this.figures[sheetId]?.[figureId];
|
|
@@ -37279,11 +37363,9 @@ class FigurePlugin extends CorePlugin {
|
|
|
37279
37363
|
// ---------------------------------------------------------------------------
|
|
37280
37364
|
import(data) {
|
|
37281
37365
|
for (let sheet of data.sheets) {
|
|
37282
|
-
const figures
|
|
37283
|
-
|
|
37284
|
-
|
|
37285
|
-
});
|
|
37286
|
-
this.figures[sheet.id] = figures;
|
|
37366
|
+
for (const figure of sheet.figures) {
|
|
37367
|
+
this.addFigure(figure, sheet.id);
|
|
37368
|
+
}
|
|
37287
37369
|
}
|
|
37288
37370
|
}
|
|
37289
37371
|
export(data) {
|
|
@@ -37307,10 +37389,10 @@ class FilterTable {
|
|
|
37307
37389
|
this.filters = [];
|
|
37308
37390
|
this.zone = zone;
|
|
37309
37391
|
const uuid = new UuidGenerator();
|
|
37310
|
-
this.id = uuid.
|
|
37392
|
+
this.id = uuid.smallUuid();
|
|
37311
37393
|
for (const i of range(zone.left, zone.right + 1)) {
|
|
37312
37394
|
const filterZone = { ...this.zone, left: i, right: i };
|
|
37313
|
-
this.filters.push(new Filter(uuid.
|
|
37395
|
+
this.filters.push(new Filter(uuid.smallUuid(), filterZone));
|
|
37314
37396
|
}
|
|
37315
37397
|
}
|
|
37316
37398
|
/** Get zone of the table without the headers */
|
|
@@ -37512,7 +37594,7 @@ class FiltersPlugin extends CorePlugin {
|
|
|
37512
37594
|
if (filters.length < zoneToDimension(zone).numberOfCols) {
|
|
37513
37595
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
37514
37596
|
if (!filters.find((filter) => filter.col === col)) {
|
|
37515
|
-
filters.push(new Filter(this.uuidGenerator.
|
|
37597
|
+
filters.push(new Filter(this.uuidGenerator.smallUuid(), { ...zone, left: col, right: col }));
|
|
37516
37598
|
}
|
|
37517
37599
|
}
|
|
37518
37600
|
filters.sort((f1, f2) => f1.col - f2.col);
|
|
@@ -39001,6 +39083,9 @@ class SheetPlugin extends CorePlugin {
|
|
|
39001
39083
|
case "CREATE_SHEET": {
|
|
39002
39084
|
return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
|
|
39003
39085
|
}
|
|
39086
|
+
case "DUPLICATE_SHEET": {
|
|
39087
|
+
return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
|
|
39088
|
+
}
|
|
39004
39089
|
case "MOVE_SHEET":
|
|
39005
39090
|
try {
|
|
39006
39091
|
const currentIndex = this.orderedSheetIds.findIndex((id) => id === cmd.sheetId);
|
|
@@ -39013,7 +39098,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
39013
39098
|
case "RENAME_SHEET":
|
|
39014
39099
|
return this.isRenameAllowed(cmd);
|
|
39015
39100
|
case "DELETE_SHEET":
|
|
39016
|
-
return this.
|
|
39101
|
+
return this.getVisibleSheetIds().length > 1
|
|
39017
39102
|
? "Success" /* CommandResult.Success */
|
|
39018
39103
|
: "NotEnoughSheets" /* CommandResult.NotEnoughSheets */;
|
|
39019
39104
|
case "ADD_COLUMNS_ROWS":
|
|
@@ -39826,6 +39911,10 @@ class SheetPlugin extends CorePlugin {
|
|
|
39826
39911
|
checkZonesAreInSheet(cmd) {
|
|
39827
39912
|
if (!("sheetId" in cmd))
|
|
39828
39913
|
return "Success" /* CommandResult.Success */;
|
|
39914
|
+
if ("ranges" in cmd &&
|
|
39915
|
+
cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
39916
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
39917
|
+
}
|
|
39829
39918
|
return this.checkZonesExistInSheet(cmd.sheetId, this.getCommandZones(cmd));
|
|
39830
39919
|
}
|
|
39831
39920
|
}
|
|
@@ -39845,7 +39934,10 @@ class HeaderGroupingPlugin extends CorePlugin {
|
|
|
39845
39934
|
allowDispatch(cmd) {
|
|
39846
39935
|
switch (cmd.type) {
|
|
39847
39936
|
case "GROUP_HEADERS": {
|
|
39848
|
-
const { start, end } = cmd;
|
|
39937
|
+
const { start, end, sheetId } = cmd;
|
|
39938
|
+
if (!this.getters.tryGetSheet(sheetId)) {
|
|
39939
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
39940
|
+
}
|
|
39849
39941
|
if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
|
|
39850
39942
|
return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
|
|
39851
39943
|
}
|
|
@@ -39858,7 +39950,10 @@ class HeaderGroupingPlugin extends CorePlugin {
|
|
|
39858
39950
|
break;
|
|
39859
39951
|
}
|
|
39860
39952
|
case "UNGROUP_HEADERS": {
|
|
39861
|
-
const { start, end } = cmd;
|
|
39953
|
+
const { start, end, sheetId } = cmd;
|
|
39954
|
+
if (!this.getters.tryGetSheet(sheetId)) {
|
|
39955
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
39956
|
+
}
|
|
39862
39957
|
if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
|
|
39863
39958
|
return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
|
|
39864
39959
|
}
|
|
@@ -39869,6 +39964,9 @@ class HeaderGroupingPlugin extends CorePlugin {
|
|
|
39869
39964
|
}
|
|
39870
39965
|
case "UNFOLD_HEADER_GROUP":
|
|
39871
39966
|
case "FOLD_HEADER_GROUP":
|
|
39967
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
39968
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
39969
|
+
}
|
|
39872
39970
|
const group = this.findGroupWithStartEnd(cmd.sheetId, cmd.dimension, cmd.start, cmd.end);
|
|
39873
39971
|
if (!group) {
|
|
39874
39972
|
return "UnknownHeaderGroup" /* CommandResult.UnknownHeaderGroup */;
|
|
@@ -44138,6 +44236,9 @@ function updateChartRangesTransformation(toTransform, executed) {
|
|
|
44138
44236
|
};
|
|
44139
44237
|
}
|
|
44140
44238
|
function createSheetTransformation(toTransform, executed) {
|
|
44239
|
+
if (toTransform.sheetId === executed.sheetId) {
|
|
44240
|
+
toTransform = { ...toTransform, sheetId: `${toTransform.sheetId}~` };
|
|
44241
|
+
}
|
|
44141
44242
|
if (toTransform.name === executed.name) {
|
|
44142
44243
|
return {
|
|
44143
44244
|
...toTransform,
|
|
@@ -44774,21 +44875,14 @@ class Session extends EventBus {
|
|
|
44774
44875
|
if (!message)
|
|
44775
44876
|
return;
|
|
44776
44877
|
if (message.type === "REMOTE_REVISION") {
|
|
44777
|
-
|
|
44878
|
+
let revision = this.revisions.get(message.nextRevisionId);
|
|
44778
44879
|
if (revision.commands.length === 0) {
|
|
44779
44880
|
/**
|
|
44780
|
-
* The command is empty, we have to
|
|
44881
|
+
* The command is empty, we have to rebase all the next local revisions
|
|
44781
44882
|
* to avoid issues with undo/redo
|
|
44782
44883
|
*/
|
|
44783
|
-
this.revisions.
|
|
44784
|
-
|
|
44785
|
-
.filter((message) => message.type === "REMOTE_REVISION")
|
|
44786
|
-
.map((message) => message.nextRevisionId);
|
|
44787
|
-
this.trigger("pending-revisions-dropped", { revisionIds });
|
|
44788
|
-
this.waitingAck = false;
|
|
44789
|
-
this.waitingUndoRedoAck = false;
|
|
44790
|
-
this.pendingMessages = [];
|
|
44791
|
-
return;
|
|
44884
|
+
this.revisions.rebase(revision.id);
|
|
44885
|
+
revision = this.revisions.get(message.nextRevisionId);
|
|
44792
44886
|
}
|
|
44793
44887
|
message = {
|
|
44794
44888
|
...message,
|
|
@@ -44812,7 +44906,6 @@ class Session extends EventBus {
|
|
|
44812
44906
|
switch (message.type) {
|
|
44813
44907
|
case "REMOTE_REVISION":
|
|
44814
44908
|
case "REVISION_REDONE":
|
|
44815
|
-
case "REVISION_UNDONE":
|
|
44816
44909
|
case "SNAPSHOT_CREATED":
|
|
44817
44910
|
this.waitingAck = false;
|
|
44818
44911
|
this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
|
|
@@ -44820,6 +44913,25 @@ class Session extends EventBus {
|
|
|
44820
44913
|
this.processedRevisions.add(message.nextRevisionId);
|
|
44821
44914
|
this.sendPendingMessage();
|
|
44822
44915
|
break;
|
|
44916
|
+
case "REVISION_UNDONE": {
|
|
44917
|
+
this.waitingAck = false;
|
|
44918
|
+
this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
|
|
44919
|
+
const firstPendingRevisionId = this.pendingMessages.findIndex((message) => message.type === "REMOTE_REVISION");
|
|
44920
|
+
if (firstPendingRevisionId !== -1) {
|
|
44921
|
+
/**
|
|
44922
|
+
* Some revisions undergo transformations that may cause issues with
|
|
44923
|
+
* undo/redo if the transformation is destructive (we don't get back
|
|
44924
|
+
* the original command by transforming it with the inverse).
|
|
44925
|
+
* To prevent these problems, we must rebase all subsequent local
|
|
44926
|
+
* revisions.
|
|
44927
|
+
*/
|
|
44928
|
+
this.revisions.rebase(this.pendingMessages[firstPendingRevisionId].nextRevisionId);
|
|
44929
|
+
}
|
|
44930
|
+
this.serverRevisionId = message.nextRevisionId;
|
|
44931
|
+
this.processedRevisions.add(message.nextRevisionId);
|
|
44932
|
+
this.sendPendingMessage();
|
|
44933
|
+
break;
|
|
44934
|
+
}
|
|
44823
44935
|
}
|
|
44824
44936
|
}
|
|
44825
44937
|
isAlreadyProcessed(message) {
|
|
@@ -45524,7 +45636,9 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
45524
45636
|
const cfInTarget = this.getters
|
|
45525
45637
|
.getConditionalFormats(targetSheetId)
|
|
45526
45638
|
.find((cf) => cf.stopIfTrue === originCF.stopIfTrue && deepEquals(cf.rule, originCF.rule));
|
|
45527
|
-
return cfInTarget
|
|
45639
|
+
return cfInTarget
|
|
45640
|
+
? cfInTarget
|
|
45641
|
+
: { ...originCF, id: this.uuidGenerator.smallUuid(), ranges: [] };
|
|
45528
45642
|
}
|
|
45529
45643
|
pasteDataValidation(origin, target) {
|
|
45530
45644
|
const rule = this.getters.getValidationRuleForCell(origin);
|
|
@@ -45556,7 +45670,7 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
45556
45670
|
originRule.isBlocking === rule.isBlocking);
|
|
45557
45671
|
return ruleInTargetSheet
|
|
45558
45672
|
? ruleInTargetSheet
|
|
45559
|
-
: { ...originRule, id: this.uuidGenerator.
|
|
45673
|
+
: { ...originRule, id: this.uuidGenerator.smallUuid(), ranges: [] };
|
|
45560
45674
|
}
|
|
45561
45675
|
/**
|
|
45562
45676
|
* Add or remove XCs to a given data validation rule.
|
|
@@ -47748,6 +47862,10 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
47748
47862
|
*/
|
|
47749
47863
|
checkZonesAreInSheet(cmd) {
|
|
47750
47864
|
const sheetId = "sheetId" in cmd ? cmd.sheetId : this.getters.tryGetActiveSheetId();
|
|
47865
|
+
if ("ranges" in cmd &&
|
|
47866
|
+
cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
47867
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
47868
|
+
}
|
|
47751
47869
|
const zones = this.getters.getCommandZones(cmd);
|
|
47752
47870
|
if (!sheetId && zones.length > 0) {
|
|
47753
47871
|
return "NoActiveSheet" /* CommandResult.NoActiveSheet */;
|
|
@@ -47796,23 +47914,23 @@ const uuidGenerator = new UuidGenerator();
|
|
|
47796
47914
|
function repeatCreateChartCommand(getters, cmd) {
|
|
47797
47915
|
return {
|
|
47798
47916
|
...repeatSheetDependantCommand(getters, cmd),
|
|
47799
|
-
id: uuidGenerator.
|
|
47917
|
+
id: uuidGenerator.smallUuid(),
|
|
47800
47918
|
};
|
|
47801
47919
|
}
|
|
47802
47920
|
function repeatCreateImageCommand(getters, cmd) {
|
|
47803
47921
|
return {
|
|
47804
47922
|
...repeatSheetDependantCommand(getters, cmd),
|
|
47805
|
-
figureId: uuidGenerator.
|
|
47923
|
+
figureId: uuidGenerator.smallUuid(),
|
|
47806
47924
|
};
|
|
47807
47925
|
}
|
|
47808
47926
|
function repeatCreateFigureCommand(getters, cmd) {
|
|
47809
47927
|
const newCmd = repeatSheetDependantCommand(getters, cmd);
|
|
47810
|
-
newCmd.figure.id = uuidGenerator.
|
|
47928
|
+
newCmd.figure.id = uuidGenerator.smallUuid();
|
|
47811
47929
|
return newCmd;
|
|
47812
47930
|
}
|
|
47813
47931
|
function repeatCreateSheetCommand(getters, cmd) {
|
|
47814
47932
|
const newCmd = deepCopy(cmd);
|
|
47815
|
-
newCmd.sheetId = uuidGenerator.
|
|
47933
|
+
newCmd.sheetId = uuidGenerator.smallUuid();
|
|
47816
47934
|
const sheetName = cmd.name || getters.getSheet(getters.getActiveSheetId()).name;
|
|
47817
47935
|
// Extract the prefix of the sheet name (everything before the number at the end of the name)
|
|
47818
47936
|
const namePrefix = sheetName.match(/(.+?)\d*$/)?.[1] || sheetName;
|
|
@@ -48007,7 +48125,6 @@ class HistoryPlugin extends UIPlugin {
|
|
|
48007
48125
|
super(config);
|
|
48008
48126
|
this.session = config.session;
|
|
48009
48127
|
this.session.on("new-local-state-update", this, this.onNewLocalStateUpdate);
|
|
48010
|
-
this.session.on("pending-revisions-dropped", this, ({ revisionIds }) => this.drop(revisionIds));
|
|
48011
48128
|
this.session.on("snapshot", this, () => {
|
|
48012
48129
|
this.undoStack = [];
|
|
48013
48130
|
this.redoStack = [];
|
|
@@ -48077,10 +48194,6 @@ class HistoryPlugin extends UIPlugin {
|
|
|
48077
48194
|
const lastNonRedoRevision = this.getPossibleRevisionToRepeat();
|
|
48078
48195
|
return canRepeatRevision(lastNonRedoRevision);
|
|
48079
48196
|
}
|
|
48080
|
-
drop(revisionIds) {
|
|
48081
|
-
this.undoStack = this.undoStack.filter((id) => !revisionIds.includes(id));
|
|
48082
|
-
this.redoStack = [];
|
|
48083
|
-
}
|
|
48084
48197
|
onNewLocalStateUpdate({ id }) {
|
|
48085
48198
|
this.undoStack.push(id);
|
|
48086
48199
|
this.redoStack = [];
|
|
@@ -48347,7 +48460,7 @@ class ClipboardFigureState {
|
|
|
48347
48460
|
x: maxX < width ? 0 : Math.min(targetX, maxX - width),
|
|
48348
48461
|
y: maxY < height ? 0 : Math.min(targetY, maxY - height),
|
|
48349
48462
|
};
|
|
48350
|
-
const newId = new UuidGenerator().
|
|
48463
|
+
const newId = new UuidGenerator().smallUuid();
|
|
48351
48464
|
this.copiedFigureContent.paste(sheetId, newId, position, { height, width });
|
|
48352
48465
|
if (this.operation === "CUT") {
|
|
48353
48466
|
this.dispatch("DELETE_FIGURE", {
|
|
@@ -50050,23 +50163,7 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
50050
50163
|
gridSelection: deepCopy(gridSelection),
|
|
50051
50164
|
};
|
|
50052
50165
|
}
|
|
50053
|
-
|
|
50054
|
-
const currentSheetIds = this.getters.getVisibleSheetIds();
|
|
50055
|
-
this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
|
|
50056
|
-
if (this.activeSheet.id in this.sheetsData) {
|
|
50057
|
-
const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
|
|
50058
|
-
this.selectCell(anchor.cell.col, anchor.cell.row);
|
|
50059
|
-
}
|
|
50060
|
-
else {
|
|
50061
|
-
this.selectCell(0, 0);
|
|
50062
|
-
}
|
|
50063
|
-
const { col, row } = this.gridSelection.anchor.cell;
|
|
50064
|
-
this.moveClient({
|
|
50065
|
-
sheetId: this.getters.getActiveSheetId(),
|
|
50066
|
-
col,
|
|
50067
|
-
row,
|
|
50068
|
-
});
|
|
50069
|
-
}
|
|
50166
|
+
this.fallbackToVisibleSheet();
|
|
50070
50167
|
const sheetId = this.getters.getActiveSheetId();
|
|
50071
50168
|
this.gridSelection.zones = this.gridSelection.zones.map((z) => this.getters.expandZone(sheetId, z));
|
|
50072
50169
|
this.gridSelection.anchor.zone = this.getters.expandZone(sheetId, this.gridSelection.anchor.zone);
|
|
@@ -50076,6 +50173,7 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
50076
50173
|
}
|
|
50077
50174
|
}
|
|
50078
50175
|
finalize() {
|
|
50176
|
+
this.fallbackToVisibleSheet();
|
|
50079
50177
|
/** Any change to the selection has to be reflected in the selection processor. */
|
|
50080
50178
|
this.selection.resetDefaultAnchor(this, deepCopy(this.gridSelection.anchor));
|
|
50081
50179
|
}
|
|
@@ -50427,6 +50525,25 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
50427
50525
|
}
|
|
50428
50526
|
return "Success" /* CommandResult.Success */;
|
|
50429
50527
|
}
|
|
50528
|
+
fallbackToVisibleSheet() {
|
|
50529
|
+
if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
|
|
50530
|
+
const currentSheetIds = this.getters.getVisibleSheetIds();
|
|
50531
|
+
this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
|
|
50532
|
+
if (this.activeSheet.id in this.sheetsData) {
|
|
50533
|
+
const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
|
|
50534
|
+
this.selectCell(anchor.cell.col, anchor.cell.row);
|
|
50535
|
+
}
|
|
50536
|
+
else {
|
|
50537
|
+
this.selectCell(0, 0);
|
|
50538
|
+
}
|
|
50539
|
+
const { col, row } = this.gridSelection.anchor.cell;
|
|
50540
|
+
this.moveClient({
|
|
50541
|
+
sheetId: this.getters.getActiveSheetId(),
|
|
50542
|
+
col,
|
|
50543
|
+
row,
|
|
50544
|
+
});
|
|
50545
|
+
}
|
|
50546
|
+
}
|
|
50430
50547
|
//-------------------------------------------
|
|
50431
50548
|
// Helpers for extensions
|
|
50432
50549
|
// ------------------------------------------
|
|
@@ -51574,7 +51691,9 @@ class HeaderPositionsUIPlugin extends UIPlugin {
|
|
|
51574
51691
|
case "UNGROUP_HEADERS":
|
|
51575
51692
|
case "GROUP_HEADERS":
|
|
51576
51693
|
case "CREATE_SHEET":
|
|
51577
|
-
this.
|
|
51694
|
+
if (this.getters.tryGetSheet(cmd.sheetId)) {
|
|
51695
|
+
this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
|
|
51696
|
+
}
|
|
51578
51697
|
break;
|
|
51579
51698
|
case "DUPLICATE_SHEET":
|
|
51580
51699
|
this.headerPositions[cmd.sheetIdTo] = deepCopy(this.headerPositions[cmd.sheetId]);
|
|
@@ -51582,12 +51701,14 @@ class HeaderPositionsUIPlugin extends UIPlugin {
|
|
|
51582
51701
|
}
|
|
51583
51702
|
}
|
|
51584
51703
|
finalize() {
|
|
51585
|
-
|
|
51586
|
-
|
|
51704
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
51705
|
+
// sheets can be created without this plugin being aware of it
|
|
51706
|
+
// in concurrent situations.
|
|
51707
|
+
if (this.isDirty || !this.headerPositions[sheetId]) {
|
|
51587
51708
|
this.headerPositions[sheetId] = this.computeHeaderPositionsOfSheet(sheetId);
|
|
51588
51709
|
}
|
|
51589
|
-
this.isDirty = false;
|
|
51590
51710
|
}
|
|
51711
|
+
this.isDirty = false;
|
|
51591
51712
|
}
|
|
51592
51713
|
/**
|
|
51593
51714
|
* Returns the size, start and end coordinates of a column on an unfolded sheet
|
|
@@ -52271,7 +52392,7 @@ class BottomBar extends owl.Component {
|
|
|
52271
52392
|
clickAddSheet(ev) {
|
|
52272
52393
|
const activeSheetId = this.env.model.getters.getActiveSheetId();
|
|
52273
52394
|
const position = this.env.model.getters.getSheetIds().findIndex((sheetId) => sheetId === activeSheetId) + 1;
|
|
52274
|
-
const sheetId = this.env.model.uuidGenerator.
|
|
52395
|
+
const sheetId = this.env.model.uuidGenerator.smallUuid();
|
|
52275
52396
|
const name = this.env.model.getters.getNextSheetName(_t("Sheet"));
|
|
52276
52397
|
this.env.model.dispatch("CREATE_SHEET", { sheetId, position, name });
|
|
52277
52398
|
this.env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
|
|
@@ -53333,7 +53454,7 @@ css /* scss */ `
|
|
|
53333
53454
|
.o-font-size-editor {
|
|
53334
53455
|
height: calc(100% - 4px);
|
|
53335
53456
|
input.o-font-size {
|
|
53336
|
-
outline
|
|
53457
|
+
outline: none;
|
|
53337
53458
|
height: 20px;
|
|
53338
53459
|
width: 23px;
|
|
53339
53460
|
}
|
|
@@ -54508,7 +54629,7 @@ class Tree {
|
|
|
54508
54629
|
}
|
|
54509
54630
|
/**
|
|
54510
54631
|
* Drop the operation and all following operations in every
|
|
54511
|
-
*
|
|
54632
|
+
* branches
|
|
54512
54633
|
*/
|
|
54513
54634
|
drop(operationId) {
|
|
54514
54635
|
for (const branch of this.branches) {
|
|
@@ -54813,9 +54934,16 @@ class SelectiveHistory {
|
|
|
54813
54934
|
this.fastForward();
|
|
54814
54935
|
this.insert(redoId, this.buildEmpty(redoId), insertAfter);
|
|
54815
54936
|
}
|
|
54816
|
-
|
|
54937
|
+
rebase(operationId) {
|
|
54938
|
+
const operation = this.get(operationId);
|
|
54939
|
+
const execution = [...this.tree.execution(this.HEAD_BRANCH).startAfter(operationId)];
|
|
54817
54940
|
this.revertBefore(operationId);
|
|
54941
|
+
const baseId = this.HEAD_OPERATION.id;
|
|
54818
54942
|
this.tree.drop(operationId);
|
|
54943
|
+
this.insert(operationId, operation, baseId);
|
|
54944
|
+
for (const { operation } of execution) {
|
|
54945
|
+
this.insert(operation.id, operation.data, this.HEAD_OPERATION.id);
|
|
54946
|
+
}
|
|
54819
54947
|
}
|
|
54820
54948
|
getRevertedExecution() {
|
|
54821
54949
|
const data = [];
|
|
@@ -57392,6 +57520,11 @@ class Model extends EventBus {
|
|
|
57392
57520
|
dispatch: (command) => {
|
|
57393
57521
|
const result = this.checkDispatchAllowed(command);
|
|
57394
57522
|
if (!result.isSuccessful) {
|
|
57523
|
+
// core views plugins need to be invalidated
|
|
57524
|
+
this.dispatchToHandlers(this.coreHandlers, {
|
|
57525
|
+
type: "UNDO",
|
|
57526
|
+
commands: [command],
|
|
57527
|
+
});
|
|
57395
57528
|
return;
|
|
57396
57529
|
}
|
|
57397
57530
|
this.isReplayingCommand = true;
|
|
@@ -57420,7 +57553,7 @@ class Model extends EventBus {
|
|
|
57420
57553
|
}
|
|
57421
57554
|
setupConfig(config) {
|
|
57422
57555
|
const client = config.client || {
|
|
57423
|
-
id: this.uuidGenerator.
|
|
57556
|
+
id: this.uuidGenerator.smallUuid(),
|
|
57424
57557
|
name: _t("Anonymous").toString(),
|
|
57425
57558
|
};
|
|
57426
57559
|
const transportService = config.transportService || new LocalTransportService();
|
|
@@ -57841,6 +57974,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
57841
57974
|
exports.tokenize = tokenize;
|
|
57842
57975
|
|
|
57843
57976
|
|
|
57844
|
-
__info__.version = "17.0.
|
|
57845
|
-
__info__.date = "2025-02-
|
|
57846
|
-
__info__.hash = "
|
|
57977
|
+
__info__.version = "17.0.50";
|
|
57978
|
+
__info__.date = "2025-02-14T08:37:34.289Z";
|
|
57979
|
+
__info__.hash = "cc1037d";
|