@odoo/o-spreadsheet 18.1.7 → 18.1.8
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 +166 -111
- package/dist/o-spreadsheet.d.ts +18 -2
- package/dist/o-spreadsheet.esm.js +166 -111
- package/dist/o-spreadsheet.iife.js +166 -111
- package/dist/o-spreadsheet.iife.min.js +151 -147
- package/dist/o_spreadsheet.xml +16 -14
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 18.1.
|
|
6
|
-
* @date 2025-02-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.1.8
|
|
6
|
+
* @date 2025-02-14T08:42:08.322Z
|
|
7
|
+
* @hash 02682f4
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -6481,6 +6481,33 @@ function drawDecoratedText(context, text, position, underline = false, strikethr
|
|
|
6481
6481
|
* https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
|
|
6482
6482
|
* */
|
|
6483
6483
|
class UuidGenerator {
|
|
6484
|
+
/**
|
|
6485
|
+
* Generates a custom UUID using a simple 36^12 method (8-character alphanumeric string with lowercase letters)
|
|
6486
|
+
* This has a higher chance of collision than a UUIDv4, but not only faster to generate than an UUIDV4,
|
|
6487
|
+
* it also has a smaller size, which is preferable to alleviate the overall data size.
|
|
6488
|
+
*
|
|
6489
|
+
* This method is preferable when generating uuids for the core data (sheetId, figureId, etc)
|
|
6490
|
+
* as they will appear several times in the revisions and local history.
|
|
6491
|
+
*
|
|
6492
|
+
*/
|
|
6493
|
+
smallUuid() {
|
|
6494
|
+
//@ts-ignore
|
|
6495
|
+
if (window.crypto && window.crypto.getRandomValues) {
|
|
6496
|
+
//@ts-ignore
|
|
6497
|
+
return ([1e7] + -1e3).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
|
|
6498
|
+
}
|
|
6499
|
+
else {
|
|
6500
|
+
// mainly for jest and other browsers that do not have the crypto functionality
|
|
6501
|
+
return "xxxxxxxx-xxxx".replace(/[xy]/g, function (c) {
|
|
6502
|
+
const r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
|
|
6503
|
+
return v.toString(16);
|
|
6504
|
+
});
|
|
6505
|
+
}
|
|
6506
|
+
}
|
|
6507
|
+
/**
|
|
6508
|
+
* Generates an UUIDV4, has astronomically low chance of collision, but is larger in size than the smallUuid.
|
|
6509
|
+
* This method should be used when you need to avoid collisions at all costs, like the id of a revision.
|
|
6510
|
+
*/
|
|
6484
6511
|
uuidv4() {
|
|
6485
6512
|
//@ts-ignore
|
|
6486
6513
|
if (window.crypto && window.crypto.getRandomValues) {
|
|
@@ -8515,7 +8542,7 @@ class ChartClipboardHandler extends AbstractFigureClipboardHandler {
|
|
|
8515
8542
|
};
|
|
8516
8543
|
}
|
|
8517
8544
|
getPasteTarget(sheetId, target, content, options) {
|
|
8518
|
-
const newId = new UuidGenerator().
|
|
8545
|
+
const newId = new UuidGenerator().smallUuid();
|
|
8519
8546
|
return { zones: [], figureId: newId, sheetId };
|
|
8520
8547
|
}
|
|
8521
8548
|
paste(target, clippedContent, options) {
|
|
@@ -8681,7 +8708,7 @@ class ConditionalFormatClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8681
8708
|
if (!targetCF && queuedCfs) {
|
|
8682
8709
|
targetCF = queuedCfs.find((queued) => queued.cf.stopIfTrue === originCF.stopIfTrue && deepEquals(queued.cf.rule, originCF.rule))?.cf;
|
|
8683
8710
|
}
|
|
8684
|
-
return targetCF || { ...originCF, id: this.uuidGenerator.
|
|
8711
|
+
return targetCF || { ...originCF, id: this.uuidGenerator.smallUuid(), ranges: [] };
|
|
8685
8712
|
}
|
|
8686
8713
|
}
|
|
8687
8714
|
|
|
@@ -8774,7 +8801,7 @@ class DataValidationClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8774
8801
|
}
|
|
8775
8802
|
return (targetRule || {
|
|
8776
8803
|
...originRule,
|
|
8777
|
-
id: newId ? this.uuidGenerator.
|
|
8804
|
+
id: newId ? this.uuidGenerator.smallUuid() : originRule.id,
|
|
8778
8805
|
ranges: [],
|
|
8779
8806
|
});
|
|
8780
8807
|
}
|
|
@@ -8836,7 +8863,7 @@ class ImageClipboardHandler extends AbstractFigureClipboardHandler {
|
|
|
8836
8863
|
};
|
|
8837
8864
|
}
|
|
8838
8865
|
getPasteTarget(sheetId, target, content, options) {
|
|
8839
|
-
const newId = new UuidGenerator().
|
|
8866
|
+
const newId = new UuidGenerator().smallUuid();
|
|
8840
8867
|
return { sheetId, zones: [], figureId: newId };
|
|
8841
8868
|
}
|
|
8842
8869
|
paste(target, clippedContent, options) {
|
|
@@ -15111,7 +15138,7 @@ const SORTN = {
|
|
|
15111
15138
|
}
|
|
15112
15139
|
}
|
|
15113
15140
|
},
|
|
15114
|
-
isExported:
|
|
15141
|
+
isExported: false,
|
|
15115
15142
|
};
|
|
15116
15143
|
// -----------------------------------------------------------------------------
|
|
15117
15144
|
// UNIQUE
|
|
@@ -27624,7 +27651,7 @@ function forceUnicityOfFigure(data) {
|
|
|
27624
27651
|
for (const sheet of data.sheets || []) {
|
|
27625
27652
|
for (const figure of sheet.figures || []) {
|
|
27626
27653
|
if (figureIds.has(figure.id)) {
|
|
27627
|
-
figure.id += uuidGenerator.
|
|
27654
|
+
figure.id += uuidGenerator.smallUuid();
|
|
27628
27655
|
}
|
|
27629
27656
|
figureIds.add(figure.id);
|
|
27630
27657
|
}
|
|
@@ -28209,9 +28236,7 @@ function getBarChartData(definition, dataSets, labelRange, getters) {
|
|
|
28209
28236
|
const labelValues = getChartLabelValues(getters, dataSets, labelRange);
|
|
28210
28237
|
let labels = labelValues.formattedValues;
|
|
28211
28238
|
let dataSetsValues = getChartDatasetValues(getters, dataSets);
|
|
28212
|
-
if (definition.dataSetsHaveTitle
|
|
28213
|
-
dataSetsValues[0] &&
|
|
28214
|
-
labels.length > dataSetsValues[0].data.length) {
|
|
28239
|
+
if (shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false)) {
|
|
28215
28240
|
labels.shift();
|
|
28216
28241
|
}
|
|
28217
28242
|
({ labels, dataSetsValues } = filterInvalidDataPoints(labels, dataSetsValues));
|
|
@@ -28260,13 +28285,12 @@ function getPyramidChartData(definition, dataSets, labelRange, getters) {
|
|
|
28260
28285
|
};
|
|
28261
28286
|
}
|
|
28262
28287
|
function getLineChartData(definition, dataSets, labelRange, getters) {
|
|
28263
|
-
const axisType = getChartAxisType(definition, labelRange, getters);
|
|
28288
|
+
const axisType = getChartAxisType(definition, dataSets, labelRange, getters);
|
|
28264
28289
|
const labelValues = getChartLabelValues(getters, dataSets, labelRange);
|
|
28265
28290
|
let labels = axisType === "linear" ? labelValues.values : labelValues.formattedValues;
|
|
28266
28291
|
let dataSetsValues = getChartDatasetValues(getters, dataSets);
|
|
28267
|
-
|
|
28268
|
-
|
|
28269
|
-
labels.length > dataSetsValues[0].data.length) {
|
|
28292
|
+
const removeFirstLabel = shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false);
|
|
28293
|
+
if (removeFirstLabel) {
|
|
28270
28294
|
labels.shift();
|
|
28271
28295
|
}
|
|
28272
28296
|
({ labels, dataSetsValues } = filterInvalidDataPoints(labels, dataSetsValues));
|
|
@@ -28278,7 +28302,7 @@ function getLineChartData(definition, dataSets, labelRange, getters) {
|
|
|
28278
28302
|
}
|
|
28279
28303
|
const leftAxisFormat = getChartDatasetFormat(getters, dataSets, "left");
|
|
28280
28304
|
const rightAxisFormat = getChartDatasetFormat(getters, dataSets, "right");
|
|
28281
|
-
const labelsFormat = getChartLabelFormat(getters, labelRange);
|
|
28305
|
+
const labelsFormat = getChartLabelFormat(getters, labelRange, removeFirstLabel);
|
|
28282
28306
|
const axisFormats = { y: leftAxisFormat, y1: rightAxisFormat, x: labelsFormat };
|
|
28283
28307
|
const trendDataSetsValues = [];
|
|
28284
28308
|
for (const index in dataSetsValues) {
|
|
@@ -28314,9 +28338,7 @@ function getPieChartData(definition, dataSets, labelRange, getters) {
|
|
|
28314
28338
|
const labelValues = getChartLabelValues(getters, dataSets, labelRange);
|
|
28315
28339
|
let labels = labelValues.formattedValues;
|
|
28316
28340
|
let dataSetsValues = getChartDatasetValues(getters, dataSets);
|
|
28317
|
-
if (definition.dataSetsHaveTitle
|
|
28318
|
-
dataSetsValues[0] &&
|
|
28319
|
-
labels.length > dataSetsValues[0].data.length) {
|
|
28341
|
+
if (shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false)) {
|
|
28320
28342
|
labels.shift();
|
|
28321
28343
|
}
|
|
28322
28344
|
({ labels, dataSetsValues } = filterInvalidDataPoints(labels, dataSetsValues));
|
|
@@ -28336,9 +28358,7 @@ function getRadarChartData(definition, dataSets, labelRange, getters) {
|
|
|
28336
28358
|
const labelValues = getChartLabelValues(getters, dataSets, labelRange);
|
|
28337
28359
|
let labels = labelValues.formattedValues;
|
|
28338
28360
|
let dataSetsValues = getChartDatasetValues(getters, dataSets);
|
|
28339
|
-
if (definition.dataSetsHaveTitle
|
|
28340
|
-
dataSetsValues[0] &&
|
|
28341
|
-
labels.length > dataSetsValues[0].data.length) {
|
|
28361
|
+
if (shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false)) {
|
|
28342
28362
|
labels.shift();
|
|
28343
28363
|
}
|
|
28344
28364
|
({ labels, dataSetsValues } = filterInvalidDataPoints(labels, dataSetsValues));
|
|
@@ -28358,7 +28378,7 @@ function getRadarChartData(definition, dataSets, labelRange, getters) {
|
|
|
28358
28378
|
function getGeoChartData(definition, dataSets, labelRange, getters) {
|
|
28359
28379
|
const labelValues = getChartLabelValues(getters, dataSets, labelRange);
|
|
28360
28380
|
let labels = labelValues.formattedValues;
|
|
28361
|
-
if (definition.dataSetsHaveTitle) {
|
|
28381
|
+
if (shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false)) {
|
|
28362
28382
|
labels.shift();
|
|
28363
28383
|
}
|
|
28364
28384
|
let dataSetsValues = getChartDatasetValues(getters, dataSets);
|
|
@@ -28519,36 +28539,41 @@ function normalizeLabels(labels, newLabels, config) {
|
|
|
28519
28539
|
}
|
|
28520
28540
|
return { normalizedLabels, normalizedNewLabels };
|
|
28521
28541
|
}
|
|
28522
|
-
function getChartAxisType(
|
|
28523
|
-
if (isDateChart(
|
|
28542
|
+
function getChartAxisType(definition, dataSets, labelRange, getters) {
|
|
28543
|
+
if (isDateChart(definition, dataSets, labelRange, getters) && isLuxonTimeAdapterInstalled()) {
|
|
28524
28544
|
return "time";
|
|
28525
28545
|
}
|
|
28526
|
-
if (isLinearChart(
|
|
28546
|
+
if (isLinearChart(definition, dataSets, labelRange, getters)) {
|
|
28527
28547
|
return "linear";
|
|
28528
28548
|
}
|
|
28529
28549
|
return "category";
|
|
28530
28550
|
}
|
|
28531
|
-
function isDateChart(definition, labelRange, getters) {
|
|
28532
|
-
return !definition.labelsAsText && canBeDateChart(labelRange, getters);
|
|
28551
|
+
function isDateChart(definition, dataSets, labelRange, getters) {
|
|
28552
|
+
return !definition.labelsAsText && canBeDateChart(definition, dataSets, labelRange, getters);
|
|
28533
28553
|
}
|
|
28534
|
-
function isLinearChart(definition, labelRange, getters) {
|
|
28535
|
-
return !definition.labelsAsText && canBeLinearChart(labelRange, getters);
|
|
28554
|
+
function isLinearChart(definition, dataSets, labelRange, getters) {
|
|
28555
|
+
return !definition.labelsAsText && canBeLinearChart(definition, dataSets, labelRange, getters);
|
|
28536
28556
|
}
|
|
28537
|
-
function canChartParseLabels(labelRange, getters) {
|
|
28538
|
-
return canBeDateChart(
|
|
28557
|
+
function canChartParseLabels(definition, dataSets, labelRange, getters) {
|
|
28558
|
+
return (canBeDateChart(definition, dataSets, labelRange, getters) ||
|
|
28559
|
+
canBeLinearChart(definition, dataSets, labelRange, getters));
|
|
28539
28560
|
}
|
|
28540
|
-
function canBeDateChart(labelRange, getters) {
|
|
28541
|
-
if (!labelRange || !canBeLinearChart(labelRange, getters)) {
|
|
28561
|
+
function canBeDateChart(definition, dataSets, labelRange, getters) {
|
|
28562
|
+
if (!labelRange || !canBeLinearChart(definition, dataSets, labelRange, getters)) {
|
|
28542
28563
|
return false;
|
|
28543
28564
|
}
|
|
28544
|
-
const
|
|
28565
|
+
const removeFirstLabel = shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false);
|
|
28566
|
+
const labelFormat = getChartLabelFormat(getters, labelRange, removeFirstLabel);
|
|
28545
28567
|
return Boolean(labelFormat && timeFormatLuxonCompatible.test(labelFormat));
|
|
28546
28568
|
}
|
|
28547
|
-
function canBeLinearChart(labelRange, getters) {
|
|
28569
|
+
function canBeLinearChart(definition, dataSets, labelRange, getters) {
|
|
28548
28570
|
if (!labelRange) {
|
|
28549
28571
|
return false;
|
|
28550
28572
|
}
|
|
28551
28573
|
const labels = getters.getRangeValues(labelRange);
|
|
28574
|
+
if (shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false)) {
|
|
28575
|
+
labels.shift();
|
|
28576
|
+
}
|
|
28552
28577
|
if (labels.some((label) => isNaN(Number(label)) && label)) {
|
|
28553
28578
|
return false;
|
|
28554
28579
|
}
|
|
@@ -28657,17 +28682,15 @@ function aggregateDataForLabels(labels, datasets) {
|
|
|
28657
28682
|
})),
|
|
28658
28683
|
};
|
|
28659
28684
|
}
|
|
28660
|
-
function getChartLabelFormat(getters, range) {
|
|
28685
|
+
function getChartLabelFormat(getters, range, shouldRemoveFirstLabel) {
|
|
28661
28686
|
if (!range)
|
|
28662
28687
|
return undefined;
|
|
28663
|
-
const { sheetId, zone
|
|
28664
|
-
|
|
28665
|
-
|
|
28666
|
-
|
|
28667
|
-
return format;
|
|
28668
|
-
}
|
|
28688
|
+
const { sheetId, zone } = range;
|
|
28689
|
+
const formats = positions(zone).map((position) => getters.getEvaluatedCell({ sheetId, ...position }).format);
|
|
28690
|
+
if (shouldRemoveFirstLabel) {
|
|
28691
|
+
formats.shift();
|
|
28669
28692
|
}
|
|
28670
|
-
return undefined;
|
|
28693
|
+
return formats.find((format) => format !== undefined);
|
|
28671
28694
|
}
|
|
28672
28695
|
function getChartLabelValues(getters, dataSets, labelRange) {
|
|
28673
28696
|
let labels = { values: [], formattedValues: [] };
|
|
@@ -32900,7 +32923,7 @@ const linkSheet = {
|
|
|
32900
32923
|
const deleteSheet = {
|
|
32901
32924
|
name: _t("Delete"),
|
|
32902
32925
|
isVisible: (env) => {
|
|
32903
|
-
return env.model.getters.
|
|
32926
|
+
return env.model.getters.getVisibleSheetIds().length > 1;
|
|
32904
32927
|
},
|
|
32905
32928
|
execute: (env) => env.askConfirmation(_t("Are you sure you want to delete this sheet?"), () => {
|
|
32906
32929
|
env.model.dispatch("DELETE_SHEET", { sheetId: env.model.getters.getActiveSheetId() });
|
|
@@ -32911,7 +32934,7 @@ const duplicateSheet = {
|
|
|
32911
32934
|
name: _t("Duplicate"),
|
|
32912
32935
|
execute: (env) => {
|
|
32913
32936
|
const sheetIdFrom = env.model.getters.getActiveSheetId();
|
|
32914
|
-
const sheetIdTo = env.model.uuidGenerator.
|
|
32937
|
+
const sheetIdTo = env.model.uuidGenerator.smallUuid();
|
|
32915
32938
|
env.model.dispatch("DUPLICATE_SHEET", {
|
|
32916
32939
|
sheetId: sheetIdFrom,
|
|
32917
32940
|
sheetIdTo,
|
|
@@ -33614,20 +33637,21 @@ function getSmartChartDefinition(zone, getters) {
|
|
|
33614
33637
|
}
|
|
33615
33638
|
// Only display legend for several datasets.
|
|
33616
33639
|
const newLegendPos = dataSetZone.right === dataSetZone.left ? "none" : "top";
|
|
33617
|
-
const
|
|
33618
|
-
|
|
33619
|
-
|
|
33620
|
-
|
|
33621
|
-
|
|
33622
|
-
|
|
33623
|
-
|
|
33624
|
-
|
|
33625
|
-
|
|
33626
|
-
|
|
33627
|
-
|
|
33628
|
-
|
|
33629
|
-
|
|
33630
|
-
|
|
33640
|
+
const lineChartDefinition = {
|
|
33641
|
+
title: {},
|
|
33642
|
+
dataSets,
|
|
33643
|
+
labelsAsText: false,
|
|
33644
|
+
stacked: false,
|
|
33645
|
+
aggregated: false,
|
|
33646
|
+
cumulative: false,
|
|
33647
|
+
labelRange: labelRangeXc,
|
|
33648
|
+
type: "line",
|
|
33649
|
+
dataSetsHaveTitle,
|
|
33650
|
+
legendPosition: newLegendPos,
|
|
33651
|
+
};
|
|
33652
|
+
const chart = new LineChart(lineChartDefinition, sheetId, getters);
|
|
33653
|
+
if (canChartParseLabels(lineChartDefinition, chart.dataSets, chart.labelRange, getters)) {
|
|
33654
|
+
return lineChartDefinition;
|
|
33631
33655
|
}
|
|
33632
33656
|
const _dataSets = createDataSets(getters, dataSets, sheetId, dataSetsHaveTitle);
|
|
33633
33657
|
if (singleColumn &&
|
|
@@ -34041,7 +34065,7 @@ const HIDE_ROWS_NAME = (env) => {
|
|
|
34041
34065
|
//------------------------------------------------------------------------------
|
|
34042
34066
|
const CREATE_CHART = (env) => {
|
|
34043
34067
|
const getters = env.model.getters;
|
|
34044
|
-
const id = env.model.uuidGenerator.
|
|
34068
|
+
const id = env.model.uuidGenerator.smallUuid();
|
|
34045
34069
|
const sheetId = getters.getActiveSheetId();
|
|
34046
34070
|
if (getZoneArea(env.model.getters.getSelectedZone()) === 1) {
|
|
34047
34071
|
env.model.selection.selectTableAroundSelection();
|
|
@@ -34064,8 +34088,8 @@ const CREATE_CHART = (env) => {
|
|
|
34064
34088
|
// Pivots
|
|
34065
34089
|
//------------------------------------------------------------------------------
|
|
34066
34090
|
const CREATE_PIVOT = (env) => {
|
|
34067
|
-
const pivotId = env.model.uuidGenerator.
|
|
34068
|
-
const newSheetId = env.model.uuidGenerator.
|
|
34091
|
+
const pivotId = env.model.uuidGenerator.smallUuid();
|
|
34092
|
+
const newSheetId = env.model.uuidGenerator.smallUuid();
|
|
34069
34093
|
const result = env.model.dispatch("INSERT_NEW_PIVOT", { pivotId, newSheetId });
|
|
34070
34094
|
if (result.isSuccessful) {
|
|
34071
34095
|
env.openSidePanel("PivotSidePanel", { pivotId });
|
|
@@ -34124,7 +34148,7 @@ async function requestImage(env) {
|
|
|
34124
34148
|
const CREATE_IMAGE = async (env) => {
|
|
34125
34149
|
if (env.imageProvider) {
|
|
34126
34150
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
34127
|
-
const figureId = env.model.uuidGenerator.
|
|
34151
|
+
const figureId = env.model.uuidGenerator.smallUuid();
|
|
34128
34152
|
const image = await requestImage(env);
|
|
34129
34153
|
if (!image) {
|
|
34130
34154
|
throw new Error("No image provider was given to the environment");
|
|
@@ -34677,7 +34701,7 @@ const insertCheckbox = {
|
|
|
34677
34701
|
ranges,
|
|
34678
34702
|
sheetId,
|
|
34679
34703
|
rule: {
|
|
34680
|
-
id: env.model.uuidGenerator.
|
|
34704
|
+
id: env.model.uuidGenerator.smallUuid(),
|
|
34681
34705
|
criterion: {
|
|
34682
34706
|
type: "isBoolean",
|
|
34683
34707
|
values: [],
|
|
@@ -34693,7 +34717,7 @@ const insertDropdown = {
|
|
|
34693
34717
|
const zones = env.model.getters.getSelectedZones();
|
|
34694
34718
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
34695
34719
|
const ranges = zones.map((zone) => env.model.getters.getRangeDataFromZone(sheetId, zone));
|
|
34696
|
-
const ruleID = env.model.uuidGenerator.
|
|
34720
|
+
const ruleID = env.model.uuidGenerator.smallUuid();
|
|
34697
34721
|
env.model.dispatch("ADD_DATA_VALIDATION_RULE", {
|
|
34698
34722
|
ranges,
|
|
34699
34723
|
sheetId,
|
|
@@ -34724,7 +34748,7 @@ const insertSheet = {
|
|
|
34724
34748
|
execute: (env) => {
|
|
34725
34749
|
const activeSheetId = env.model.getters.getActiveSheetId();
|
|
34726
34750
|
const position = env.model.getters.getSheetIds().indexOf(activeSheetId) + 1;
|
|
34727
|
-
const sheetId = env.model.uuidGenerator.
|
|
34751
|
+
const sheetId = env.model.uuidGenerator.smallUuid();
|
|
34728
34752
|
env.model.dispatch("CREATE_SHEET", { sheetId, position });
|
|
34729
34753
|
env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
|
|
34730
34754
|
},
|
|
@@ -39213,7 +39237,7 @@ class LineConfigPanel extends GenericChartConfigPanel {
|
|
|
39213
39237
|
get canTreatLabelsAsText() {
|
|
39214
39238
|
const chart = this.env.model.getters.getChart(this.props.figureId);
|
|
39215
39239
|
if (chart && chart instanceof LineChart) {
|
|
39216
|
-
return canChartParseLabels(chart.labelRange, this.env.model.getters);
|
|
39240
|
+
return canChartParseLabels(chart.getDefinition(), chart.dataSets, chart.labelRange, this.env.model.getters);
|
|
39217
39241
|
}
|
|
39218
39242
|
return false;
|
|
39219
39243
|
}
|
|
@@ -39290,7 +39314,7 @@ class ScatterConfigPanel extends GenericChartConfigPanel {
|
|
|
39290
39314
|
get canTreatLabelsAsText() {
|
|
39291
39315
|
const chart = this.env.model.getters.getChart(this.props.figureId);
|
|
39292
39316
|
if (chart && chart instanceof ScatterChart) {
|
|
39293
|
-
return canChartParseLabels(chart.labelRange, this.env.model.getters);
|
|
39317
|
+
return canChartParseLabels(chart.getDefinition(), chart.dataSets, chart.labelRange, this.env.model.getters);
|
|
39294
39318
|
}
|
|
39295
39319
|
return false;
|
|
39296
39320
|
}
|
|
@@ -42068,7 +42092,7 @@ class ConditionalFormattingPanel extends owl.Component {
|
|
|
42068
42092
|
this.originalEditedCf = undefined;
|
|
42069
42093
|
}
|
|
42070
42094
|
addConditionalFormat() {
|
|
42071
|
-
const cfId = this.env.model.uuidGenerator.
|
|
42095
|
+
const cfId = this.env.model.uuidGenerator.smallUuid();
|
|
42072
42096
|
this.env.model.dispatch("ADD_CONDITIONAL_FORMAT", {
|
|
42073
42097
|
sheetId: this.activeSheetId,
|
|
42074
42098
|
ranges: this.env.model.getters
|
|
@@ -43338,7 +43362,7 @@ class DataValidationEditor extends owl.Component {
|
|
|
43338
43362
|
.getSelectedZones()
|
|
43339
43363
|
.map((zone) => zoneToXc(this.env.model.getters.getUnboundedZone(sheetId, zone)));
|
|
43340
43364
|
return {
|
|
43341
|
-
id: this.env.model.uuidGenerator.
|
|
43365
|
+
id: this.env.model.uuidGenerator.smallUuid(),
|
|
43342
43366
|
criterion: { type: "textContains", values: [""] },
|
|
43343
43367
|
ranges,
|
|
43344
43368
|
};
|
|
@@ -44956,8 +44980,8 @@ class PivotTitleSection extends owl.Component {
|
|
|
44956
44980
|
return this.env.model.getters.getPivotDisplayName(this.props.pivotId);
|
|
44957
44981
|
}
|
|
44958
44982
|
duplicatePivot() {
|
|
44959
|
-
const newPivotId = this.env.model.uuidGenerator.
|
|
44960
|
-
const newSheetId = this.env.model.uuidGenerator.
|
|
44983
|
+
const newPivotId = this.env.model.uuidGenerator.smallUuid();
|
|
44984
|
+
const newSheetId = this.env.model.uuidGenerator.smallUuid();
|
|
44961
44985
|
const result = this.env.model.dispatch("DUPLICATE_PIVOT_IN_NEW_SHEET", {
|
|
44962
44986
|
pivotId: this.props.pivotId,
|
|
44963
44987
|
newPivotId,
|
|
@@ -47582,7 +47606,7 @@ class TableStyleEditorPanel extends owl.Component {
|
|
|
47582
47606
|
this.state.selectedTemplateName = templateName;
|
|
47583
47607
|
}
|
|
47584
47608
|
onConfirm() {
|
|
47585
|
-
const tableStyleId = this.props.styleId || this.env.model.uuidGenerator.
|
|
47609
|
+
const tableStyleId = this.props.styleId || this.env.model.uuidGenerator.smallUuid();
|
|
47586
47610
|
this.env.model.dispatch("CREATE_TABLE_STYLE", {
|
|
47587
47611
|
tableStyleId,
|
|
47588
47612
|
tableStyleName: this.state.styleName,
|
|
@@ -56156,7 +56180,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
56156
56180
|
? "Success" /* CommandResult.Success */
|
|
56157
56181
|
: "InvalidColor" /* CommandResult.InvalidColor */;
|
|
56158
56182
|
case "DELETE_SHEET":
|
|
56159
|
-
return this.
|
|
56183
|
+
return this.getVisibleSheetIds().length > 1
|
|
56160
56184
|
? "Success" /* CommandResult.Success */
|
|
56161
56185
|
: "NotEnoughSheets" /* CommandResult.NotEnoughSheets */;
|
|
56162
56186
|
case "ADD_COLUMNS_ROWS":
|
|
@@ -63515,6 +63539,15 @@ class Session extends EventBus {
|
|
|
63515
63539
|
}
|
|
63516
63540
|
this.sendPendingMessage();
|
|
63517
63541
|
}
|
|
63542
|
+
dropPendingRevision(revisionId) {
|
|
63543
|
+
this.revisions.drop(revisionId);
|
|
63544
|
+
const revisionIds = this.pendingMessages
|
|
63545
|
+
.filter((message) => message.type === "REMOTE_REVISION")
|
|
63546
|
+
.map((message) => message.nextRevisionId);
|
|
63547
|
+
this.trigger("pending-revisions-dropped", { revisionIds });
|
|
63548
|
+
this.waitingAck = false;
|
|
63549
|
+
this.waitingUndoRedoAck = false;
|
|
63550
|
+
}
|
|
63518
63551
|
/**
|
|
63519
63552
|
* Send the next pending message
|
|
63520
63553
|
*/
|
|
@@ -63529,13 +63562,7 @@ class Session extends EventBus {
|
|
|
63529
63562
|
* The command is empty, we have to drop all the next local revisions
|
|
63530
63563
|
* to avoid issues with undo/redo
|
|
63531
63564
|
*/
|
|
63532
|
-
this.
|
|
63533
|
-
const revisionIds = this.pendingMessages
|
|
63534
|
-
.filter((message) => message.type === "REMOTE_REVISION")
|
|
63535
|
-
.map((message) => message.nextRevisionId);
|
|
63536
|
-
this.trigger("pending-revisions-dropped", { revisionIds });
|
|
63537
|
-
this.waitingAck = false;
|
|
63538
|
-
this.waitingUndoRedoAck = false;
|
|
63565
|
+
this.dropPendingRevision(revision.id);
|
|
63539
63566
|
this.pendingMessages = [];
|
|
63540
63567
|
return;
|
|
63541
63568
|
}
|
|
@@ -63562,7 +63589,6 @@ class Session extends EventBus {
|
|
|
63562
63589
|
switch (message.type) {
|
|
63563
63590
|
case "REMOTE_REVISION":
|
|
63564
63591
|
case "REVISION_REDONE":
|
|
63565
|
-
case "REVISION_UNDONE":
|
|
63566
63592
|
case "SNAPSHOT_CREATED":
|
|
63567
63593
|
this.waitingAck = false;
|
|
63568
63594
|
this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
|
|
@@ -63571,6 +63597,27 @@ class Session extends EventBus {
|
|
|
63571
63597
|
this.lastRevisionMessage = message;
|
|
63572
63598
|
this.sendPendingMessage();
|
|
63573
63599
|
break;
|
|
63600
|
+
case "REVISION_UNDONE": {
|
|
63601
|
+
this.waitingAck = false;
|
|
63602
|
+
this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
|
|
63603
|
+
const pendingRemoteRevisions = this.pendingMessages.filter((message) => message.type === "REMOTE_REVISION");
|
|
63604
|
+
const firstTransformedRevisionIndex = pendingRemoteRevisions.findIndex((message) => !deepEquals(message.commands, this.revisions.get(message.nextRevisionId).commands));
|
|
63605
|
+
if (firstTransformedRevisionIndex !== -1) {
|
|
63606
|
+
/**
|
|
63607
|
+
* Some revisions undergo transformations that may cause issues with
|
|
63608
|
+
* undo/redo if the transformation is destructive (we don't get back
|
|
63609
|
+
* the original command by transforming it with the inverse).
|
|
63610
|
+
* To prevent these problems, we must discard all subsequent local
|
|
63611
|
+
* revisions.
|
|
63612
|
+
*/
|
|
63613
|
+
this.dropPendingRevision(this.pendingMessages[firstTransformedRevisionIndex].nextRevisionId);
|
|
63614
|
+
this.pendingMessages = this.pendingMessages.slice(0, firstTransformedRevisionIndex);
|
|
63615
|
+
}
|
|
63616
|
+
this.serverRevisionId = message.nextRevisionId;
|
|
63617
|
+
this.processedRevisions.add(message.nextRevisionId);
|
|
63618
|
+
this.sendPendingMessage();
|
|
63619
|
+
break;
|
|
63620
|
+
}
|
|
63574
63621
|
}
|
|
63575
63622
|
}
|
|
63576
63623
|
isAlreadyProcessed(message) {
|
|
@@ -65041,23 +65088,23 @@ const uuidGenerator = new UuidGenerator();
|
|
|
65041
65088
|
function repeatCreateChartCommand(getters, cmd) {
|
|
65042
65089
|
return {
|
|
65043
65090
|
...repeatSheetDependantCommand(getters, cmd),
|
|
65044
|
-
id: uuidGenerator.
|
|
65091
|
+
id: uuidGenerator.smallUuid(),
|
|
65045
65092
|
};
|
|
65046
65093
|
}
|
|
65047
65094
|
function repeatCreateImageCommand(getters, cmd) {
|
|
65048
65095
|
return {
|
|
65049
65096
|
...repeatSheetDependantCommand(getters, cmd),
|
|
65050
|
-
figureId: uuidGenerator.
|
|
65097
|
+
figureId: uuidGenerator.smallUuid(),
|
|
65051
65098
|
};
|
|
65052
65099
|
}
|
|
65053
65100
|
function repeatCreateFigureCommand(getters, cmd) {
|
|
65054
65101
|
const newCmd = repeatSheetDependantCommand(getters, cmd);
|
|
65055
|
-
newCmd.figure.id = uuidGenerator.
|
|
65102
|
+
newCmd.figure.id = uuidGenerator.smallUuid();
|
|
65056
65103
|
return newCmd;
|
|
65057
65104
|
}
|
|
65058
65105
|
function repeatCreateSheetCommand(getters, cmd) {
|
|
65059
65106
|
const newCmd = deepCopy(cmd);
|
|
65060
|
-
newCmd.sheetId = uuidGenerator.
|
|
65107
|
+
newCmd.sheetId = uuidGenerator.smallUuid();
|
|
65061
65108
|
const sheetName = cmd.name || getters.getSheet(getters.getActiveSheetId()).name;
|
|
65062
65109
|
// Extract the prefix of the sheet name (everything before the number at the end of the name)
|
|
65063
65110
|
const namePrefix = sheetName.match(/(.+?)\d*$/)?.[1] || sheetName;
|
|
@@ -66520,23 +66567,7 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
66520
66567
|
gridSelection: deepCopy(gridSelection),
|
|
66521
66568
|
};
|
|
66522
66569
|
}
|
|
66523
|
-
|
|
66524
|
-
const currentSheetIds = this.getters.getVisibleSheetIds();
|
|
66525
|
-
this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
|
|
66526
|
-
if (this.activeSheet.id in this.sheetsData) {
|
|
66527
|
-
const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
|
|
66528
|
-
this.selectCell(anchor.cell.col, anchor.cell.row);
|
|
66529
|
-
}
|
|
66530
|
-
else {
|
|
66531
|
-
this.selectCell(0, 0);
|
|
66532
|
-
}
|
|
66533
|
-
const { col, row } = this.gridSelection.anchor.cell;
|
|
66534
|
-
this.moveClient({
|
|
66535
|
-
sheetId: this.getters.getActiveSheetId(),
|
|
66536
|
-
col,
|
|
66537
|
-
row,
|
|
66538
|
-
});
|
|
66539
|
-
}
|
|
66570
|
+
this.fallbackToVisibleSheet();
|
|
66540
66571
|
const sheetId = this.getters.getActiveSheetId();
|
|
66541
66572
|
this.gridSelection.zones = this.gridSelection.zones.map((z) => this.getters.expandZone(sheetId, z));
|
|
66542
66573
|
this.gridSelection.anchor.zone = this.getters.expandZone(sheetId, this.gridSelection.anchor.zone);
|
|
@@ -66546,6 +66577,7 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
66546
66577
|
}
|
|
66547
66578
|
}
|
|
66548
66579
|
finalize() {
|
|
66580
|
+
this.fallbackToVisibleSheet();
|
|
66549
66581
|
/** Any change to the selection has to be reflected in the selection processor. */
|
|
66550
66582
|
this.selection.resetDefaultAnchor(this, deepCopy(this.gridSelection.anchor));
|
|
66551
66583
|
}
|
|
@@ -66856,6 +66888,25 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
66856
66888
|
}
|
|
66857
66889
|
return "Success" /* CommandResult.Success */;
|
|
66858
66890
|
}
|
|
66891
|
+
fallbackToVisibleSheet() {
|
|
66892
|
+
if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
|
|
66893
|
+
const currentSheetIds = this.getters.getVisibleSheetIds();
|
|
66894
|
+
this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
|
|
66895
|
+
if (this.activeSheet.id in this.sheetsData) {
|
|
66896
|
+
const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
|
|
66897
|
+
this.selectCell(anchor.cell.col, anchor.cell.row);
|
|
66898
|
+
}
|
|
66899
|
+
else {
|
|
66900
|
+
this.selectCell(0, 0);
|
|
66901
|
+
}
|
|
66902
|
+
const { col, row } = this.gridSelection.anchor.cell;
|
|
66903
|
+
this.moveClient({
|
|
66904
|
+
sheetId: this.getters.getActiveSheetId(),
|
|
66905
|
+
col,
|
|
66906
|
+
row,
|
|
66907
|
+
});
|
|
66908
|
+
}
|
|
66909
|
+
}
|
|
66859
66910
|
//-------------------------------------------
|
|
66860
66911
|
// Helpers for extensions
|
|
66861
66912
|
// ------------------------------------------
|
|
@@ -68856,7 +68907,7 @@ class BottomBar extends owl.Component {
|
|
|
68856
68907
|
clickAddSheet(ev) {
|
|
68857
68908
|
const activeSheetId = this.env.model.getters.getActiveSheetId();
|
|
68858
68909
|
const position = this.env.model.getters.getSheetIds().findIndex((sheetId) => sheetId === activeSheetId) + 1;
|
|
68859
|
-
const sheetId = this.env.model.uuidGenerator.
|
|
68910
|
+
const sheetId = this.env.model.uuidGenerator.smallUuid();
|
|
68860
68911
|
const name = this.env.model.getters.getNextSheetName(_t("Sheet"));
|
|
68861
68912
|
this.env.model.dispatch("CREATE_SHEET", { sheetId, position, name });
|
|
68862
68913
|
this.env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
|
|
@@ -69871,6 +69922,10 @@ const FX_SVG = /*xml*/ `
|
|
|
69871
69922
|
</svg>
|
|
69872
69923
|
`;
|
|
69873
69924
|
css /* scss */ `
|
|
69925
|
+
.o-topbar-composer-container {
|
|
69926
|
+
height: ${TOPBAR_TOOLBAR_HEIGHT}px;
|
|
69927
|
+
}
|
|
69928
|
+
|
|
69874
69929
|
.o-topbar-composer {
|
|
69875
69930
|
height: fit-content;
|
|
69876
69931
|
margin-top: -1px;
|
|
@@ -71144,7 +71199,7 @@ class Tree {
|
|
|
71144
71199
|
}
|
|
71145
71200
|
/**
|
|
71146
71201
|
* Drop the operation and all following operations in every
|
|
71147
|
-
*
|
|
71202
|
+
* branches
|
|
71148
71203
|
*/
|
|
71149
71204
|
drop(operationId) {
|
|
71150
71205
|
for (const branch of this.branches) {
|
|
@@ -74589,7 +74644,7 @@ class Model extends EventBus {
|
|
|
74589
74644
|
}
|
|
74590
74645
|
setupConfig(config) {
|
|
74591
74646
|
const client = config.client || {
|
|
74592
|
-
id: this.uuidGenerator.
|
|
74647
|
+
id: this.uuidGenerator.smallUuid(),
|
|
74593
74648
|
name: _t("Anonymous").toString(),
|
|
74594
74649
|
};
|
|
74595
74650
|
const transportService = config.transportService || new LocalTransportService();
|
|
@@ -75112,6 +75167,6 @@ exports.tokenColors = tokenColors;
|
|
|
75112
75167
|
exports.tokenize = tokenize;
|
|
75113
75168
|
|
|
75114
75169
|
|
|
75115
|
-
__info__.version = "18.1.
|
|
75116
|
-
__info__.date = "2025-02-
|
|
75117
|
-
__info__.hash = "
|
|
75170
|
+
__info__.version = "18.1.8";
|
|
75171
|
+
__info__.date = "2025-02-14T08:42:08.322Z";
|
|
75172
|
+
__info__.hash = "02682f4";
|
package/dist/o-spreadsheet.d.ts
CHANGED
|
@@ -1247,6 +1247,7 @@ declare class Session extends EventBus<CollaborativeEvent> {
|
|
|
1247
1247
|
private onClientJoined;
|
|
1248
1248
|
private onClientLeft;
|
|
1249
1249
|
private sendUpdateMessage;
|
|
1250
|
+
private dropPendingRevision;
|
|
1250
1251
|
/**
|
|
1251
1252
|
* Send the next pending message
|
|
1252
1253
|
*/
|
|
@@ -1446,6 +1447,20 @@ declare function splitReference(ref: string): {
|
|
|
1446
1447
|
declare function computeTextWidth(context: CanvasRenderingContext2D, text: string, style: Style, fontUnit?: "px" | "pt"): number;
|
|
1447
1448
|
|
|
1448
1449
|
declare class UuidGenerator {
|
|
1450
|
+
/**
|
|
1451
|
+
* Generates a custom UUID using a simple 36^12 method (8-character alphanumeric string with lowercase letters)
|
|
1452
|
+
* This has a higher chance of collision than a UUIDv4, but not only faster to generate than an UUIDV4,
|
|
1453
|
+
* it also has a smaller size, which is preferable to alleviate the overall data size.
|
|
1454
|
+
*
|
|
1455
|
+
* This method is preferable when generating uuids for the core data (sheetId, figureId, etc)
|
|
1456
|
+
* as they will appear several times in the revisions and local history.
|
|
1457
|
+
*
|
|
1458
|
+
*/
|
|
1459
|
+
smallUuid(): string;
|
|
1460
|
+
/**
|
|
1461
|
+
* Generates an UUIDV4, has astronomically low chance of collision, but is larger in size than the smallUuid.
|
|
1462
|
+
* This method should be used when you need to avoid collisions at all costs, like the id of a revision.
|
|
1463
|
+
*/
|
|
1449
1464
|
uuidv4(): string;
|
|
1450
1465
|
}
|
|
1451
1466
|
|
|
@@ -2046,6 +2061,7 @@ declare class GridSelectionPlugin extends UIPlugin {
|
|
|
2046
2061
|
private onAddElements;
|
|
2047
2062
|
private onMoveElements;
|
|
2048
2063
|
private isMoveElementAllowed;
|
|
2064
|
+
private fallbackToVisibleSheet;
|
|
2049
2065
|
/**
|
|
2050
2066
|
* Clip the selection if it spans outside the sheet
|
|
2051
2067
|
*/
|
|
@@ -12668,9 +12684,9 @@ declare const chartHelpers: {
|
|
|
12668
12684
|
getGeoChartData(definition: GeoChartDefinition, dataSets: DataSet[], labelRange: Range | undefined, getters: Getters): GeoChartRuntimeGenerationArgs;
|
|
12669
12685
|
getTrendDatasetForBarChart(config: TrendConfiguration, data: any[]): chart_js.Point[] | undefined;
|
|
12670
12686
|
getTrendDatasetForLineChart(config: TrendConfiguration, data: any[], labels: string[], axisType: AxisType, locale: Locale): chart_js.Point[] | undefined;
|
|
12671
|
-
canChartParseLabels(labelRange: Range | undefined, getters: Getters): boolean;
|
|
12687
|
+
canChartParseLabels(definition: GenericDefinition<LineChartDefinition>, dataSets: DataSet[], labelRange: Range | undefined, getters: Getters): boolean;
|
|
12672
12688
|
getData(getters: Getters, ds: DataSet): (CellValue | undefined)[];
|
|
12673
|
-
getChartLabelFormat(getters: Getters, range: Range | undefined): Format | undefined;
|
|
12689
|
+
getChartLabelFormat(getters: Getters, range: Range | undefined, shouldRemoveFirstLabel: boolean): Format | undefined;
|
|
12674
12690
|
getBarChartDatasets(definition: GenericDefinition<BarChartDefinition>, args: ChartRuntimeGenerationArgs): chart_js.ChartDataset<"line" | "bar">[];
|
|
12675
12691
|
getWaterfallDatasetAndLabels(definition: GenericDefinition<WaterfallChartDefinition>, args: ChartRuntimeGenerationArgs): {
|
|
12676
12692
|
datasets: chart_js.ChartDataset[];
|