@odoo/o-spreadsheet 18.1.18 → 18.1.20
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 +617 -97
- package/dist/o-spreadsheet.d.ts +285 -156
- package/dist/o-spreadsheet.esm.js +617 -97
- package/dist/o-spreadsheet.iife.js +617 -97
- package/dist/o-spreadsheet.iife.min.js +423 -387
- package/dist/o_spreadsheet.xml +64 -16
- 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-05-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.1.20
|
|
6
|
+
* @date 2025-05-13T17:52:28.174Z
|
|
7
|
+
* @hash 3e43a46
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -3348,7 +3348,7 @@ function isDateAfter(date, dateAfter) {
|
|
|
3348
3348
|
*/
|
|
3349
3349
|
const getFormulaNumberRegex = memoize(function getFormulaNumberRegex(decimalSeparator) {
|
|
3350
3350
|
decimalSeparator = escapeRegExp(decimalSeparator);
|
|
3351
|
-
return new RegExp(`(?:^-?\\d+(?:${decimalSeparator}?\\d*(?:e
|
|
3351
|
+
return new RegExp(`(?:^-?\\d+(?:${decimalSeparator}?\\d*(?:e(\\+|-)?\\d+)?)?|^-?${decimalSeparator}\\d+)(?!\\w|!)`);
|
|
3352
3352
|
});
|
|
3353
3353
|
const getNumberRegex = memoize(function getNumberRegex(locale) {
|
|
3354
3354
|
const decimalSeparator = escapeRegExp(locale.decimalSeparator);
|
|
@@ -6273,6 +6273,32 @@ function moveHeaderIndexesOnHeaderDeletion(deletedHeaders, headers) {
|
|
|
6273
6273
|
})
|
|
6274
6274
|
.filter(isDefined);
|
|
6275
6275
|
}
|
|
6276
|
+
function getNextSheetName(existingNames, baseName = "Sheet") {
|
|
6277
|
+
let i = 1;
|
|
6278
|
+
let name = `${baseName}${i}`;
|
|
6279
|
+
while (existingNames.includes(name)) {
|
|
6280
|
+
name = `${baseName}${i}`;
|
|
6281
|
+
i++;
|
|
6282
|
+
}
|
|
6283
|
+
return name;
|
|
6284
|
+
}
|
|
6285
|
+
function getDuplicateSheetName(nameToDuplicate, existingNames) {
|
|
6286
|
+
let i = 1;
|
|
6287
|
+
const baseName = _t("Copy of %s", nameToDuplicate);
|
|
6288
|
+
let name = baseName.toString();
|
|
6289
|
+
while (existingNames.includes(name)) {
|
|
6290
|
+
name = `${baseName} (${i})`;
|
|
6291
|
+
i++;
|
|
6292
|
+
}
|
|
6293
|
+
return name;
|
|
6294
|
+
}
|
|
6295
|
+
function isSheetNameEqual(name1, name2) {
|
|
6296
|
+
if (name1 === undefined || name2 === undefined) {
|
|
6297
|
+
return false;
|
|
6298
|
+
}
|
|
6299
|
+
return (getUnquotedSheetName(name1.trim().toUpperCase()) ===
|
|
6300
|
+
getUnquotedSheetName(name2.trim().toUpperCase()));
|
|
6301
|
+
}
|
|
6276
6302
|
|
|
6277
6303
|
function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
|
|
6278
6304
|
return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
|
|
@@ -7971,6 +7997,24 @@ const monthNumberAdapter = {
|
|
|
7971
7997
|
return `${normalizedValue}`;
|
|
7972
7998
|
},
|
|
7973
7999
|
};
|
|
8000
|
+
/**
|
|
8001
|
+
* normalizes month number + year
|
|
8002
|
+
*/
|
|
8003
|
+
const monthAdapter = {
|
|
8004
|
+
normalizeFunctionValue(value) {
|
|
8005
|
+
const date = toNumber(value, DEFAULT_LOCALE);
|
|
8006
|
+
return formatValue(date, { locale: DEFAULT_LOCALE, format: "mm/yyyy" });
|
|
8007
|
+
},
|
|
8008
|
+
toValueAndFormat(normalizedValue) {
|
|
8009
|
+
return {
|
|
8010
|
+
value: toNumber(normalizedValue, DEFAULT_LOCALE),
|
|
8011
|
+
format: "mmmm yyyy",
|
|
8012
|
+
};
|
|
8013
|
+
},
|
|
8014
|
+
toFunctionValue(normalizedValue) {
|
|
8015
|
+
return `"${normalizedValue}"`;
|
|
8016
|
+
},
|
|
8017
|
+
};
|
|
7974
8018
|
/**
|
|
7975
8019
|
* normalizes quarter number
|
|
7976
8020
|
*/
|
|
@@ -8101,6 +8145,7 @@ pivotTimeAdapterRegistry
|
|
|
8101
8145
|
.add("day_of_month", nullHandlerDecorator(dayOfMonthAdapter))
|
|
8102
8146
|
.add("iso_week_number", nullHandlerDecorator(isoWeekNumberAdapter))
|
|
8103
8147
|
.add("month_number", nullHandlerDecorator(monthNumberAdapter))
|
|
8148
|
+
.add("month", nullHandlerDecorator(monthAdapter))
|
|
8104
8149
|
.add("quarter_number", nullHandlerDecorator(quarterNumberAdapter))
|
|
8105
8150
|
.add("day_of_week", nullHandlerDecorator(dayOfWeekAdapter))
|
|
8106
8151
|
.add("hour_number", nullHandlerDecorator(hourNumberAdapter))
|
|
@@ -8117,10 +8162,9 @@ const AGGREGATOR_NAMES = {
|
|
|
8117
8162
|
avg: _t("Average"),
|
|
8118
8163
|
sum: _t("Sum"),
|
|
8119
8164
|
};
|
|
8120
|
-
const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
|
|
8121
8165
|
const AGGREGATORS_BY_FIELD_TYPE = {
|
|
8122
|
-
integer:
|
|
8123
|
-
char:
|
|
8166
|
+
integer: ["max", "min", "avg", "sum", "count_distinct", "count"],
|
|
8167
|
+
char: ["count_distinct", "count"],
|
|
8124
8168
|
boolean: ["count_distinct", "count", "bool_and", "bool_or"],
|
|
8125
8169
|
};
|
|
8126
8170
|
const AGGREGATORS = {};
|
|
@@ -8280,10 +8324,7 @@ function toNormalizedPivotValue(dimension, groupValue) {
|
|
|
8280
8324
|
return normalizer(groupValueString, dimension.granularity);
|
|
8281
8325
|
}
|
|
8282
8326
|
function normalizeDateTime(value, granularity) {
|
|
8283
|
-
|
|
8284
|
-
throw new Error("Missing granularity");
|
|
8285
|
-
}
|
|
8286
|
-
return pivotTimeAdapter(granularity).normalizeFunctionValue(value);
|
|
8327
|
+
return pivotTimeAdapter(granularity ?? "month").normalizeFunctionValue(value);
|
|
8287
8328
|
}
|
|
8288
8329
|
function toFunctionPivotValue(value, dimension) {
|
|
8289
8330
|
if (value === null) {
|
|
@@ -8295,10 +8336,7 @@ function toFunctionPivotValue(value, dimension) {
|
|
|
8295
8336
|
return pivotToFunctionValueRegistry.get(dimension.type)(value, dimension.granularity);
|
|
8296
8337
|
}
|
|
8297
8338
|
function toFunctionValueDateTime(value, granularity) {
|
|
8298
|
-
|
|
8299
|
-
throw new Error("Missing granularity");
|
|
8300
|
-
}
|
|
8301
|
-
return pivotTimeAdapter(granularity).toFunctionValue(value);
|
|
8339
|
+
return pivotTimeAdapter(granularity ?? "month").toFunctionValue(value);
|
|
8302
8340
|
}
|
|
8303
8341
|
const pivotNormalizationValueRegistry = new Registry();
|
|
8304
8342
|
pivotNormalizationValueRegistry
|
|
@@ -9478,7 +9516,10 @@ function proxifyStoreMutation(store, callback) {
|
|
|
9478
9516
|
const functionProxy = new Proxy(value, {
|
|
9479
9517
|
// trap the function call
|
|
9480
9518
|
apply(target, thisArg, argArray) {
|
|
9481
|
-
Reflect.apply(target, thisStore, argArray);
|
|
9519
|
+
const res = Reflect.apply(target, thisStore, argArray);
|
|
9520
|
+
if (res === "noStateChange") {
|
|
9521
|
+
return;
|
|
9522
|
+
}
|
|
9482
9523
|
callback();
|
|
9483
9524
|
},
|
|
9484
9525
|
});
|
|
@@ -9500,7 +9541,7 @@ function getDependencyContainer(env) {
|
|
|
9500
9541
|
const ModelStore = createAbstractStore("Model");
|
|
9501
9542
|
|
|
9502
9543
|
class RendererStore {
|
|
9503
|
-
mutators = ["register", "unRegister"];
|
|
9544
|
+
mutators = ["register", "unRegister", "drawLayer"];
|
|
9504
9545
|
renderers = {};
|
|
9505
9546
|
register(renderer) {
|
|
9506
9547
|
if (!renderer.renderingLayers.length) {
|
|
@@ -9520,14 +9561,14 @@ class RendererStore {
|
|
|
9520
9561
|
}
|
|
9521
9562
|
drawLayer(context, layer) {
|
|
9522
9563
|
const renderers = this.renderers[layer];
|
|
9523
|
-
if (
|
|
9524
|
-
|
|
9525
|
-
|
|
9526
|
-
|
|
9527
|
-
|
|
9528
|
-
|
|
9529
|
-
context.ctx.restore();
|
|
9564
|
+
if (renderers) {
|
|
9565
|
+
for (const renderer of renderers) {
|
|
9566
|
+
context.ctx.save();
|
|
9567
|
+
renderer.drawLayer(context, layer);
|
|
9568
|
+
context.ctx.restore();
|
|
9569
|
+
}
|
|
9530
9570
|
}
|
|
9571
|
+
return "noStateChange";
|
|
9531
9572
|
}
|
|
9532
9573
|
}
|
|
9533
9574
|
|
|
@@ -9580,16 +9621,17 @@ class ComposerFocusStore extends SpreadsheetStore {
|
|
|
9580
9621
|
focusComposer(listener, args) {
|
|
9581
9622
|
this.activeComposer = listener;
|
|
9582
9623
|
if (this.getters.isReadonly()) {
|
|
9583
|
-
return;
|
|
9624
|
+
return "noStateChange";
|
|
9584
9625
|
}
|
|
9585
9626
|
this._focusMode = args.focusMode || "contentFocus";
|
|
9586
9627
|
if (this._focusMode !== "inactive") {
|
|
9587
9628
|
this.setComposerContent(args);
|
|
9588
9629
|
}
|
|
9630
|
+
return;
|
|
9589
9631
|
}
|
|
9590
9632
|
focusActiveComposer(args) {
|
|
9591
9633
|
if (this.getters.isReadonly()) {
|
|
9592
|
-
return;
|
|
9634
|
+
return "noStateChange";
|
|
9593
9635
|
}
|
|
9594
9636
|
if (!this.activeComposer) {
|
|
9595
9637
|
throw new Error("No composer is registered");
|
|
@@ -9598,6 +9640,7 @@ class ComposerFocusStore extends SpreadsheetStore {
|
|
|
9598
9640
|
if (this._focusMode !== "inactive") {
|
|
9599
9641
|
this.setComposerContent(args);
|
|
9600
9642
|
}
|
|
9643
|
+
return;
|
|
9601
9644
|
}
|
|
9602
9645
|
/**
|
|
9603
9646
|
* Start the edition or update the content if it's already started.
|
|
@@ -9613,12 +9656,24 @@ class ComposerFocusStore extends SpreadsheetStore {
|
|
|
9613
9656
|
}
|
|
9614
9657
|
|
|
9615
9658
|
const chartJsExtensionRegistry = new Registry();
|
|
9616
|
-
|
|
9617
|
-
|
|
9618
|
-
|
|
9619
|
-
|
|
9659
|
+
function areChartJSExtensionsLoaded() {
|
|
9660
|
+
return !!window.Chart.registry.plugins.get("chartShowValuesPlugin");
|
|
9661
|
+
}
|
|
9662
|
+
function registerChartJSExtensions() {
|
|
9663
|
+
if (!window.Chart || areChartJSExtensionsLoaded()) {
|
|
9664
|
+
return;
|
|
9665
|
+
}
|
|
9666
|
+
for (const registryItem of chartJsExtensionRegistry.getAll()) {
|
|
9667
|
+
registryItem.register(window.Chart);
|
|
9668
|
+
}
|
|
9669
|
+
}
|
|
9670
|
+
function unregisterChartJsExtensions() {
|
|
9671
|
+
if (!window.Chart) {
|
|
9672
|
+
return;
|
|
9673
|
+
}
|
|
9674
|
+
for (const registryItem of chartJsExtensionRegistry.getAll()) {
|
|
9675
|
+
registryItem.unregister(window.Chart);
|
|
9620
9676
|
}
|
|
9621
|
-
return window.Chart;
|
|
9622
9677
|
}
|
|
9623
9678
|
|
|
9624
9679
|
const TREND_LINE_XAXIS_ID = "x1";
|
|
@@ -9935,7 +9990,7 @@ function getDefinedAxis(definition) {
|
|
|
9935
9990
|
}
|
|
9936
9991
|
function formatChartDatasetValue(axisFormats, locale) {
|
|
9937
9992
|
return (value, axisId) => {
|
|
9938
|
-
const format =
|
|
9993
|
+
const format = axisFormats?.[axisId];
|
|
9939
9994
|
return formatTickValue({ format, locale })(value);
|
|
9940
9995
|
};
|
|
9941
9996
|
}
|
|
@@ -10099,7 +10154,7 @@ function drawPieChartValues(chart, options, ctx) {
|
|
|
10099
10154
|
const y = bar.y + midRadius * Math.sin(midAngle) + 7;
|
|
10100
10155
|
ctx.fillStyle = chartFontColor(options.background);
|
|
10101
10156
|
ctx.strokeStyle = options.background || "#ffffff";
|
|
10102
|
-
const displayValue = options.callback(value);
|
|
10157
|
+
const displayValue = options.callback(value, "y");
|
|
10103
10158
|
drawTextWithBackground(displayValue, x, y, ctx);
|
|
10104
10159
|
}
|
|
10105
10160
|
}
|
|
@@ -10159,8 +10214,14 @@ function getNextNonEmptyBar(bars, startIndex) {
|
|
|
10159
10214
|
return bars.find((bar, i) => i > startIndex && bar.height !== 0);
|
|
10160
10215
|
}
|
|
10161
10216
|
|
|
10162
|
-
chartJsExtensionRegistry.add("chartShowValuesPlugin",
|
|
10163
|
-
|
|
10217
|
+
chartJsExtensionRegistry.add("chartShowValuesPlugin", {
|
|
10218
|
+
register: (Chart) => Chart.register(chartShowValuesPlugin),
|
|
10219
|
+
unregister: (Chart) => Chart.unregister(chartShowValuesPlugin),
|
|
10220
|
+
});
|
|
10221
|
+
chartJsExtensionRegistry.add("waterfallLinesPlugin", {
|
|
10222
|
+
register: (Chart) => Chart.register(waterfallLinesPlugin),
|
|
10223
|
+
unregister: (Chart) => Chart.unregister(waterfallLinesPlugin),
|
|
10224
|
+
});
|
|
10164
10225
|
class ChartJsComponent extends owl.Component {
|
|
10165
10226
|
static template = "o-spreadsheet-ChartJsComponent";
|
|
10166
10227
|
static props = {
|
|
@@ -10212,8 +10273,7 @@ class ChartJsComponent extends owl.Component {
|
|
|
10212
10273
|
createChart(chartData) {
|
|
10213
10274
|
const canvas = this.canvas.el;
|
|
10214
10275
|
const ctx = canvas.getContext("2d");
|
|
10215
|
-
|
|
10216
|
-
this.chart = new Chart(ctx, chartData);
|
|
10276
|
+
this.chart = new window.Chart(ctx, chartData);
|
|
10217
10277
|
}
|
|
10218
10278
|
updateChartJs(chartData) {
|
|
10219
10279
|
if (chartData.data && chartData.data.datasets) {
|
|
@@ -18345,7 +18405,7 @@ const IF = {
|
|
|
18345
18405
|
return { value: "" };
|
|
18346
18406
|
}
|
|
18347
18407
|
if (result.value === null) {
|
|
18348
|
-
result
|
|
18408
|
+
return { ...result, value: "" };
|
|
18349
18409
|
}
|
|
18350
18410
|
return result;
|
|
18351
18411
|
},
|
|
@@ -18366,7 +18426,7 @@ const IFERROR = {
|
|
|
18366
18426
|
return { value: "" };
|
|
18367
18427
|
}
|
|
18368
18428
|
if (result.value === null) {
|
|
18369
|
-
result
|
|
18429
|
+
return { ...result, value: "" };
|
|
18370
18430
|
}
|
|
18371
18431
|
return result;
|
|
18372
18432
|
},
|
|
@@ -18387,7 +18447,7 @@ const IFNA = {
|
|
|
18387
18447
|
return { value: "" };
|
|
18388
18448
|
}
|
|
18389
18449
|
if (result.value === null) {
|
|
18390
|
-
result
|
|
18450
|
+
return { ...result, value: "" };
|
|
18391
18451
|
}
|
|
18392
18452
|
return result;
|
|
18393
18453
|
},
|
|
@@ -18413,7 +18473,7 @@ const IFS = {
|
|
|
18413
18473
|
return { value: "" };
|
|
18414
18474
|
}
|
|
18415
18475
|
if (result.value === null) {
|
|
18416
|
-
result
|
|
18476
|
+
return { ...result, value: "" };
|
|
18417
18477
|
}
|
|
18418
18478
|
return result;
|
|
18419
18479
|
}
|
|
@@ -18531,6 +18591,11 @@ function addPivotDependencies(evalContext, coreDefinition, forMeasures) {
|
|
|
18531
18591
|
if (range === undefined || range.invalidXc || range.invalidSheetName) {
|
|
18532
18592
|
throw new InvalidReferenceError();
|
|
18533
18593
|
}
|
|
18594
|
+
if (evalContext.__originCellPosition &&
|
|
18595
|
+
range.sheetId === evalContext.__originSheetId &&
|
|
18596
|
+
isZoneInside(positionToZone(evalContext.__originCellPosition), zone)) {
|
|
18597
|
+
throw new CircularDependencyError();
|
|
18598
|
+
}
|
|
18534
18599
|
dependencies.push(range);
|
|
18535
18600
|
}
|
|
18536
18601
|
for (const measure of forMeasures) {
|
|
@@ -18979,6 +19044,9 @@ const PIVOT_VALUE = {
|
|
|
18979
19044
|
};
|
|
18980
19045
|
}
|
|
18981
19046
|
const domain = pivot.parseArgsToPivotDomain(domainArgs);
|
|
19047
|
+
if (this.getters.getActiveSheetId() === this.__originSheetId) {
|
|
19048
|
+
this.getters.getPivotPresenceTracker(pivotId)?.trackValue(_measure, domain);
|
|
19049
|
+
}
|
|
18982
19050
|
return pivot.getPivotCellValueAndFormat(_measure, domain);
|
|
18983
19051
|
},
|
|
18984
19052
|
};
|
|
@@ -19010,6 +19078,9 @@ const PIVOT_HEADER = {
|
|
|
19010
19078
|
};
|
|
19011
19079
|
}
|
|
19012
19080
|
const domain = pivot.parseArgsToPivotDomain(domainArgs);
|
|
19081
|
+
if (this.getters.getActiveSheetId() === this.__originSheetId) {
|
|
19082
|
+
this.getters.getPivotPresenceTracker(_pivotId)?.trackHeader(domain);
|
|
19083
|
+
}
|
|
19013
19084
|
const lastNode = domain.at(-1);
|
|
19014
19085
|
if (lastNode?.field === "measure") {
|
|
19015
19086
|
return pivot.getPivotMeasureValue(toString(lastNode.value), domain);
|
|
@@ -19232,6 +19303,9 @@ function isEmpty(data) {
|
|
|
19232
19303
|
return data === undefined || data.value === null;
|
|
19233
19304
|
}
|
|
19234
19305
|
const getNeutral = { number: 0, string: "", boolean: false };
|
|
19306
|
+
function areAlmostEqual(value1, value2, epsilon = 2e-16) {
|
|
19307
|
+
return Math.abs(value1 - value2) < epsilon;
|
|
19308
|
+
}
|
|
19235
19309
|
const EQ = {
|
|
19236
19310
|
description: _t("Equal."),
|
|
19237
19311
|
args: [
|
|
@@ -19253,6 +19327,9 @@ const EQ = {
|
|
|
19253
19327
|
if (typeof _value2 === "string") {
|
|
19254
19328
|
_value2 = _value2.toUpperCase();
|
|
19255
19329
|
}
|
|
19330
|
+
if (typeof _value1 === "number" && typeof _value2 === "number") {
|
|
19331
|
+
return { value: areAlmostEqual(_value1, _value2) };
|
|
19332
|
+
}
|
|
19256
19333
|
return { value: _value1 === _value2 };
|
|
19257
19334
|
},
|
|
19258
19335
|
};
|
|
@@ -19292,6 +19369,9 @@ const GT = {
|
|
|
19292
19369
|
],
|
|
19293
19370
|
compute: function (value1, value2) {
|
|
19294
19371
|
return applyRelationalOperator(value1, value2, (v1, v2) => {
|
|
19372
|
+
if (typeof v1 === "number" && typeof v2 === "number") {
|
|
19373
|
+
return !areAlmostEqual(v1, v2) && v1 > v2;
|
|
19374
|
+
}
|
|
19295
19375
|
return v1 > v2;
|
|
19296
19376
|
});
|
|
19297
19377
|
},
|
|
@@ -19307,6 +19387,9 @@ const GTE = {
|
|
|
19307
19387
|
],
|
|
19308
19388
|
compute: function (value1, value2) {
|
|
19309
19389
|
return applyRelationalOperator(value1, value2, (v1, v2) => {
|
|
19390
|
+
if (typeof v1 === "number" && typeof v2 === "number") {
|
|
19391
|
+
return areAlmostEqual(v1, v2) || v1 > v2;
|
|
19392
|
+
}
|
|
19310
19393
|
return v1 >= v2;
|
|
19311
19394
|
});
|
|
19312
19395
|
},
|
|
@@ -20913,7 +20996,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
20913
20996
|
.find((token) => {
|
|
20914
20997
|
const { xc, sheetName: sheet } = splitReference(token.value);
|
|
20915
20998
|
const sheetName = sheet || this.getters.getSheetName(this.sheetId);
|
|
20916
|
-
if (this.getters.getSheetName(activeSheetId)
|
|
20999
|
+
if (!isSheetNameEqual(this.getters.getSheetName(activeSheetId), sheetName)) {
|
|
20917
21000
|
return false;
|
|
20918
21001
|
}
|
|
20919
21002
|
const refRange = this.getters.getRangeFromSheetXC(activeSheetId, xc);
|
|
@@ -22792,6 +22875,7 @@ const CHART_COMMON_OPTIONS = {
|
|
|
22792
22875
|
},
|
|
22793
22876
|
},
|
|
22794
22877
|
animation: false,
|
|
22878
|
+
events: ["mousemove", "mouseout", "click", "touchstart", "touchmove", "mouseup"],
|
|
22795
22879
|
};
|
|
22796
22880
|
function truncateLabel(label) {
|
|
22797
22881
|
if (!label) {
|
|
@@ -22817,8 +22901,7 @@ function chartToImage(runtime, figure, type) {
|
|
|
22817
22901
|
if ("chartJsConfig" in runtime) {
|
|
22818
22902
|
const config = deepCopy(runtime.chartJsConfig);
|
|
22819
22903
|
config.plugins = [backgroundColorChartJSPlugin];
|
|
22820
|
-
const
|
|
22821
|
-
const chart = new Chart(canvas, config);
|
|
22904
|
+
const chart = new window.Chart(canvas, config);
|
|
22822
22905
|
const imgContent = chart.toBase64Image();
|
|
22823
22906
|
chart.destroy();
|
|
22824
22907
|
div.remove();
|
|
@@ -24524,7 +24607,7 @@ function getRangeSize(reference, defaultSheetIndex, data) {
|
|
|
24524
24607
|
({ xc, sheetName } = splitReference(reference));
|
|
24525
24608
|
let rangeSheetIndex;
|
|
24526
24609
|
if (sheetName) {
|
|
24527
|
-
const index = data.sheets.findIndex((sheet) => sheet.name
|
|
24610
|
+
const index = data.sheets.findIndex((sheet) => isSheetNameEqual(sheet.name, sheetName));
|
|
24528
24611
|
if (index < 0) {
|
|
24529
24612
|
throw new Error("Unable to find a sheet with the name " + sheetName);
|
|
24530
24613
|
}
|
|
@@ -24865,7 +24948,7 @@ function convertFormula(formula, data) {
|
|
|
24865
24948
|
formula = formula.replace(externalReferenceRegex, (match, externalRefId, sheetName, cellRef) => {
|
|
24866
24949
|
externalRefId = Number(externalRefId) - 1;
|
|
24867
24950
|
cellRef = cellRef.replace(/\$/g, "");
|
|
24868
|
-
const sheetIndex = data.externalBooks[externalRefId].sheetNames.findIndex((name) => name
|
|
24951
|
+
const sheetIndex = data.externalBooks[externalRefId].sheetNames.findIndex((name) => isSheetNameEqual(name, sheetName));
|
|
24869
24952
|
if (sheetIndex === -1) {
|
|
24870
24953
|
return match;
|
|
24871
24954
|
}
|
|
@@ -25516,7 +25599,7 @@ function convertPivotTableConfig(pivotTable) {
|
|
|
25516
25599
|
*/
|
|
25517
25600
|
function convertTableFormulaReferences(convertedSheets, xlsxSheets) {
|
|
25518
25601
|
for (let tableSheet of convertedSheets) {
|
|
25519
|
-
const tables = xlsxSheets.find((s) => s.sheetName
|
|
25602
|
+
const tables = xlsxSheets.find((s) => isSheetNameEqual(s.sheetName, tableSheet.name)).tables;
|
|
25520
25603
|
for (let table of tables) {
|
|
25521
25604
|
const tabRef = table.name + "[";
|
|
25522
25605
|
for (let sheet of convertedSheets) {
|
|
@@ -27950,6 +28033,7 @@ function repairInitialMessages(data, initialMessages) {
|
|
|
27950
28033
|
initialMessages = dropCommands(initialMessages, "SORT_CELLS");
|
|
27951
28034
|
initialMessages = dropCommands(initialMessages, "SET_DECIMAL");
|
|
27952
28035
|
initialMessages = fixChartDefinitions(data, initialMessages);
|
|
28036
|
+
initialMessages = fixTranslatedDuplicateSheetName(data, initialMessages);
|
|
27953
28037
|
return initialMessages;
|
|
27954
28038
|
}
|
|
27955
28039
|
/**
|
|
@@ -28049,6 +28133,40 @@ function fixChartDefinitions(data, initialMessages) {
|
|
|
28049
28133
|
}
|
|
28050
28134
|
return messages;
|
|
28051
28135
|
}
|
|
28136
|
+
function fixTranslatedDuplicateSheetName(data, initialMessages) {
|
|
28137
|
+
const sheetNames = {};
|
|
28138
|
+
for (const sheet of data.sheets || []) {
|
|
28139
|
+
sheetNames[sheet.id] = sheet.name;
|
|
28140
|
+
}
|
|
28141
|
+
const messages = [];
|
|
28142
|
+
for (const message of initialMessages) {
|
|
28143
|
+
if (message.type === "REMOTE_REVISION") {
|
|
28144
|
+
const commands = [];
|
|
28145
|
+
for (const cmd of message.commands) {
|
|
28146
|
+
switch (cmd.type) {
|
|
28147
|
+
case "DUPLICATE_SHEET":
|
|
28148
|
+
cmd.sheetNameTo =
|
|
28149
|
+
cmd.sheetNameTo ??
|
|
28150
|
+
getDuplicateSheetName(sheetNames[cmd.sheetId], Object.values(sheetNames));
|
|
28151
|
+
break;
|
|
28152
|
+
case "CREATE_SHEET":
|
|
28153
|
+
case "RENAME_SHEET":
|
|
28154
|
+
sheetNames[cmd.sheetId] = cmd.name || getNextSheetName(Object.values(sheetNames));
|
|
28155
|
+
break;
|
|
28156
|
+
}
|
|
28157
|
+
commands.push(cmd);
|
|
28158
|
+
}
|
|
28159
|
+
messages.push({
|
|
28160
|
+
...message,
|
|
28161
|
+
commands,
|
|
28162
|
+
});
|
|
28163
|
+
}
|
|
28164
|
+
else {
|
|
28165
|
+
messages.push(message);
|
|
28166
|
+
}
|
|
28167
|
+
}
|
|
28168
|
+
return initialMessages;
|
|
28169
|
+
}
|
|
28052
28170
|
// -----------------------------------------------------------------------------
|
|
28053
28171
|
// Helpers
|
|
28054
28172
|
// -----------------------------------------------------------------------------
|
|
@@ -28846,12 +28964,11 @@ function canBeLinearChart(definition, dataSets, labelRange, getters) {
|
|
|
28846
28964
|
}
|
|
28847
28965
|
let missingTimeAdapterAlreadyWarned = false;
|
|
28848
28966
|
function isLuxonTimeAdapterInstalled() {
|
|
28849
|
-
|
|
28850
|
-
if (!Chart) {
|
|
28967
|
+
if (!window.Chart) {
|
|
28851
28968
|
return false;
|
|
28852
28969
|
}
|
|
28853
28970
|
// @ts-ignore
|
|
28854
|
-
const adapter = new Chart._adapters._date({});
|
|
28971
|
+
const adapter = new window.Chart._adapters._date({});
|
|
28855
28972
|
const isInstalled = adapter._id === "luxon";
|
|
28856
28973
|
if (!isInstalled && !missingTimeAdapterAlreadyWarned) {
|
|
28857
28974
|
missingTimeAdapterAlreadyWarned = true;
|
|
@@ -29489,6 +29606,9 @@ const INTERACTIVE_LEGEND_CONFIG = {
|
|
|
29489
29606
|
target.style.cursor = "default";
|
|
29490
29607
|
},
|
|
29491
29608
|
onClick: (event, legendItem, legend) => {
|
|
29609
|
+
if (event.type !== "click") {
|
|
29610
|
+
return;
|
|
29611
|
+
}
|
|
29492
29612
|
const index = legendItem.datasetIndex;
|
|
29493
29613
|
if (!legend.legendItems || index === undefined) {
|
|
29494
29614
|
return;
|
|
@@ -32314,12 +32434,20 @@ class HoveredCellStore extends SpreadsheetStore {
|
|
|
32314
32434
|
}
|
|
32315
32435
|
}
|
|
32316
32436
|
hover(position) {
|
|
32437
|
+
if (position.col === this.col && position.row === this.row) {
|
|
32438
|
+
return "noStateChange";
|
|
32439
|
+
}
|
|
32317
32440
|
this.col = position.col;
|
|
32318
32441
|
this.row = position.row;
|
|
32442
|
+
return;
|
|
32319
32443
|
}
|
|
32320
32444
|
clear() {
|
|
32445
|
+
if (this.col === undefined && this.row === undefined) {
|
|
32446
|
+
return "noStateChange";
|
|
32447
|
+
}
|
|
32321
32448
|
this.col = undefined;
|
|
32322
32449
|
this.row = undefined;
|
|
32450
|
+
return;
|
|
32323
32451
|
}
|
|
32324
32452
|
}
|
|
32325
32453
|
|
|
@@ -32341,7 +32469,11 @@ class CellPopoverStore extends SpreadsheetStore {
|
|
|
32341
32469
|
this.persistentPopover = { col, row, sheetId, type };
|
|
32342
32470
|
}
|
|
32343
32471
|
close() {
|
|
32472
|
+
if (!this.persistentPopover) {
|
|
32473
|
+
return "noStateChange";
|
|
32474
|
+
}
|
|
32344
32475
|
this.persistentPopover = undefined;
|
|
32476
|
+
return;
|
|
32345
32477
|
}
|
|
32346
32478
|
get persistentCellPopover() {
|
|
32347
32479
|
return ((this.persistentPopover && { isOpen: true, ...this.persistentPopover }) || { isOpen: false });
|
|
@@ -33214,10 +33346,13 @@ const duplicateSheet = {
|
|
|
33214
33346
|
name: _t("Duplicate"),
|
|
33215
33347
|
execute: (env) => {
|
|
33216
33348
|
const sheetIdFrom = env.model.getters.getActiveSheetId();
|
|
33349
|
+
const sheetNameFrom = env.model.getters.getSheetName(sheetIdFrom);
|
|
33217
33350
|
const sheetIdTo = env.model.uuidGenerator.smallUuid();
|
|
33351
|
+
const sheetNameTo = env.model.getters.getDuplicateSheetName(sheetNameFrom);
|
|
33218
33352
|
env.model.dispatch("DUPLICATE_SHEET", {
|
|
33219
33353
|
sheetId: sheetIdFrom,
|
|
33220
33354
|
sheetIdTo,
|
|
33355
|
+
sheetNameTo,
|
|
33221
33356
|
});
|
|
33222
33357
|
env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom, sheetIdTo });
|
|
33223
33358
|
},
|
|
@@ -40170,10 +40305,18 @@ class ChartPanel extends owl.Component {
|
|
|
40170
40305
|
}
|
|
40171
40306
|
|
|
40172
40307
|
class DOMFocusableElementStore {
|
|
40173
|
-
mutators = ["setFocusableElement"];
|
|
40308
|
+
mutators = ["setFocusableElement", "focus"];
|
|
40174
40309
|
focusableElement = undefined;
|
|
40175
40310
|
setFocusableElement(element) {
|
|
40176
40311
|
this.focusableElement = element;
|
|
40312
|
+
return "noStateChange";
|
|
40313
|
+
}
|
|
40314
|
+
focus() {
|
|
40315
|
+
if (this.focusableElement === document.activeElement) {
|
|
40316
|
+
return "noStateChange";
|
|
40317
|
+
}
|
|
40318
|
+
this.focusableElement?.focus();
|
|
40319
|
+
return;
|
|
40177
40320
|
}
|
|
40178
40321
|
}
|
|
40179
40322
|
|
|
@@ -40763,7 +40906,7 @@ class Composer extends owl.Component {
|
|
|
40763
40906
|
if (document.activeElement === this.contentHelper.el &&
|
|
40764
40907
|
this.props.composerStore.editionMode === "inactive" &&
|
|
40765
40908
|
!this.props.isDefaultFocus) {
|
|
40766
|
-
this.DOMFocusableElementStore.
|
|
40909
|
+
this.DOMFocusableElementStore.focus();
|
|
40767
40910
|
}
|
|
40768
40911
|
});
|
|
40769
40912
|
owl.useEffect(() => {
|
|
@@ -41037,6 +41180,13 @@ class Composer extends owl.Component {
|
|
|
41037
41180
|
openAssistant() {
|
|
41038
41181
|
this.assistant.forcedClosed = false;
|
|
41039
41182
|
}
|
|
41183
|
+
onWheel(event) {
|
|
41184
|
+
// detect if scrollbar is available
|
|
41185
|
+
if (this.composerRef.el &&
|
|
41186
|
+
this.composerRef.el.scrollHeight > this.composerRef.el.clientHeight) {
|
|
41187
|
+
event.stopPropagation();
|
|
41188
|
+
}
|
|
41189
|
+
}
|
|
41040
41190
|
// ---------------------------------------------------------------------------
|
|
41041
41191
|
// Private
|
|
41042
41192
|
// ---------------------------------------------------------------------------
|
|
@@ -45974,8 +46124,8 @@ function compareDimensionValues(dimension, a, b) {
|
|
|
45974
46124
|
|
|
45975
46125
|
const NULL_SYMBOL = Symbol("NULL");
|
|
45976
46126
|
function createDate(dimension, value, locale) {
|
|
45977
|
-
const granularity = dimension.granularity;
|
|
45978
|
-
if (!
|
|
46127
|
+
const granularity = dimension.granularity || "month";
|
|
46128
|
+
if (!(granularity in MAP_VALUE_DIMENSION_DATE)) {
|
|
45979
46129
|
throw new Error(`Unknown date granularity: ${granularity}`);
|
|
45980
46130
|
}
|
|
45981
46131
|
const keyInMap = typeof value === "number" || typeof value === "string" ? value : NULL_SYMBOL;
|
|
@@ -45994,6 +46144,9 @@ function createDate(dimension, value, locale) {
|
|
|
45994
46144
|
case "month_number":
|
|
45995
46145
|
number = date.getMonth() + 1;
|
|
45996
46146
|
break;
|
|
46147
|
+
case "month":
|
|
46148
|
+
number = Math.floor(toNumber(value, locale));
|
|
46149
|
+
break;
|
|
45997
46150
|
case "iso_week_number":
|
|
45998
46151
|
number = date.getIsoWeek();
|
|
45999
46152
|
break;
|
|
@@ -46087,6 +46240,10 @@ const MAP_VALUE_DIMENSION_DATE = {
|
|
|
46087
46240
|
set: new Set(),
|
|
46088
46241
|
values: {},
|
|
46089
46242
|
},
|
|
46243
|
+
month: {
|
|
46244
|
+
set: new Set(),
|
|
46245
|
+
values: {},
|
|
46246
|
+
},
|
|
46090
46247
|
iso_week_number: {
|
|
46091
46248
|
set: new Set(),
|
|
46092
46249
|
values: {},
|
|
@@ -46297,7 +46454,7 @@ class SpreadsheetPivot {
|
|
|
46297
46454
|
const cells = this.filterDataEntriesFromDomain(this.dataEntries, domain);
|
|
46298
46455
|
const finalCell = cells[0]?.[dimension.nameWithGranularity];
|
|
46299
46456
|
if (dimension.type === "datetime") {
|
|
46300
|
-
const adapter = pivotTimeAdapter(dimension.granularity);
|
|
46457
|
+
const adapter = pivotTimeAdapter((dimension.granularity || "month"));
|
|
46301
46458
|
return adapter.toValueAndFormat(lastNode.value, this.getters.getLocale());
|
|
46302
46459
|
}
|
|
46303
46460
|
if (!finalCell) {
|
|
@@ -46415,7 +46572,7 @@ class SpreadsheetPivot {
|
|
|
46415
46572
|
if (nonEmptyCells.length === 0) {
|
|
46416
46573
|
return "integer";
|
|
46417
46574
|
}
|
|
46418
|
-
if (nonEmptyCells.every((cell) => cell.format && isDateTimeFormat(cell.format))) {
|
|
46575
|
+
if (nonEmptyCells.every((cell) => cell.type === CellValueType.number && cell.format && isDateTimeFormat(cell.format))) {
|
|
46419
46576
|
return "datetime";
|
|
46420
46577
|
}
|
|
46421
46578
|
if (nonEmptyCells.every((cell) => cell.type === CellValueType.boolean)) {
|
|
@@ -46496,7 +46653,12 @@ class SpreadsheetPivot {
|
|
|
46496
46653
|
entry[field.name] = { value: null, type: CellValueType.empty, formattedValue: "" };
|
|
46497
46654
|
}
|
|
46498
46655
|
else {
|
|
46499
|
-
|
|
46656
|
+
if (field.type === "char") {
|
|
46657
|
+
entry[field.name] = { ...cell, value: cell.formattedValue || null };
|
|
46658
|
+
}
|
|
46659
|
+
else {
|
|
46660
|
+
entry[field.name] = cell;
|
|
46661
|
+
}
|
|
46500
46662
|
}
|
|
46501
46663
|
}
|
|
46502
46664
|
entry["__count"] = { value: 1, type: CellValueType.number, formattedValue: "1" };
|
|
@@ -46510,7 +46672,7 @@ class SpreadsheetPivot {
|
|
|
46510
46672
|
for (const entry of dataEntries) {
|
|
46511
46673
|
for (const dimension of dateDimensions) {
|
|
46512
46674
|
const value = createDate(dimension, entry[dimension.fieldName]?.value || null, this.getters.getLocale());
|
|
46513
|
-
const adapter = pivotTimeAdapter(dimension.granularity);
|
|
46675
|
+
const adapter = pivotTimeAdapter((dimension.granularity || "month"));
|
|
46514
46676
|
const { format, value: valueToFormat } = adapter.toValueAndFormat(value, locale);
|
|
46515
46677
|
entry[dimension.nameWithGranularity] = {
|
|
46516
46678
|
value,
|
|
@@ -46530,6 +46692,7 @@ const dateGranularities = [
|
|
|
46530
46692
|
"year",
|
|
46531
46693
|
"quarter_number",
|
|
46532
46694
|
"month_number",
|
|
46695
|
+
"month",
|
|
46533
46696
|
"iso_week_number",
|
|
46534
46697
|
"day_of_month",
|
|
46535
46698
|
"day",
|
|
@@ -46777,7 +46940,7 @@ class PivotSidePanelStore extends SpreadsheetStore {
|
|
|
46777
46940
|
: this.datetimeGranularities);
|
|
46778
46941
|
}
|
|
46779
46942
|
for (const field of dateFields) {
|
|
46780
|
-
granularitiesPerFields[field.fieldName].delete(field.granularity);
|
|
46943
|
+
granularitiesPerFields[field.fieldName].delete(field.granularity || "month");
|
|
46781
46944
|
}
|
|
46782
46945
|
return granularitiesPerFields;
|
|
46783
46946
|
}
|
|
@@ -48952,6 +49115,8 @@ class GridComposer extends owl.Component {
|
|
|
48952
49115
|
}
|
|
48953
49116
|
get composerProps() {
|
|
48954
49117
|
const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
|
|
49118
|
+
// Remove the wrapper border width
|
|
49119
|
+
const maxHeight = this.props.gridDims.height - this.rect.y - 2 * COMPOSER_BORDER_WIDTH;
|
|
48955
49120
|
return {
|
|
48956
49121
|
rect: { ...this.rect },
|
|
48957
49122
|
delimitation: {
|
|
@@ -48969,6 +49134,7 @@ class GridComposer extends owl.Component {
|
|
|
48969
49134
|
}),
|
|
48970
49135
|
onInputContextMenu: this.props.onInputContextMenu,
|
|
48971
49136
|
composerStore: this.composerStore,
|
|
49137
|
+
inputStyle: `max-height: ${maxHeight}px;`,
|
|
48972
49138
|
};
|
|
48973
49139
|
}
|
|
48974
49140
|
get containerStyle() {
|
|
@@ -51521,10 +51687,6 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
51521
51687
|
ctx.scale(dpr, dpr);
|
|
51522
51688
|
for (const layer of OrderedLayers()) {
|
|
51523
51689
|
model.drawLayer(renderingContext, layer);
|
|
51524
|
-
// @ts-ignore 'drawLayer' is not declated as a mutator because:
|
|
51525
|
-
// it does not mutate anything. Most importantly it's used
|
|
51526
|
-
// during rendering. Invoking a mutator during rendering would
|
|
51527
|
-
// trigger another rendering, ultimately resulting in an infinite loop.
|
|
51528
51690
|
rendererStore.drawLayer(renderingContext, layer);
|
|
51529
51691
|
}
|
|
51530
51692
|
}
|
|
@@ -52214,7 +52376,7 @@ class Grid extends owl.Component {
|
|
|
52214
52376
|
this.cellPopovers = useStore(CellPopoverStore);
|
|
52215
52377
|
owl.useEffect(() => {
|
|
52216
52378
|
if (!this.sidePanel.isOpen) {
|
|
52217
|
-
this.DOMFocusableElementStore.
|
|
52379
|
+
this.DOMFocusableElementStore.focus();
|
|
52218
52380
|
}
|
|
52219
52381
|
}, () => [this.sidePanel.isOpen]);
|
|
52220
52382
|
useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
|
|
@@ -52424,7 +52586,7 @@ class Grid extends owl.Component {
|
|
|
52424
52586
|
focusDefaultElement() {
|
|
52425
52587
|
if (!this.env.model.getters.getSelectedFigureId() &&
|
|
52426
52588
|
this.composerFocusStore.activeComposer.editionMode === "inactive") {
|
|
52427
|
-
this.DOMFocusableElementStore.
|
|
52589
|
+
this.DOMFocusableElementStore.focus();
|
|
52428
52590
|
}
|
|
52429
52591
|
}
|
|
52430
52592
|
get gridEl() {
|
|
@@ -52769,6 +52931,322 @@ class Grid extends owl.Component {
|
|
|
52769
52931
|
}
|
|
52770
52932
|
}
|
|
52771
52933
|
|
|
52934
|
+
css /* scss */ `
|
|
52935
|
+
.o_pivot_html_renderer {
|
|
52936
|
+
width: 100%;
|
|
52937
|
+
border-collapse: collapse;
|
|
52938
|
+
|
|
52939
|
+
&:hover {
|
|
52940
|
+
cursor: pointer;
|
|
52941
|
+
}
|
|
52942
|
+
|
|
52943
|
+
td,
|
|
52944
|
+
th {
|
|
52945
|
+
border: 1px solid #dee2e6;
|
|
52946
|
+
background-color: #fff;
|
|
52947
|
+
padding: 0.3rem;
|
|
52948
|
+
white-space: nowrap;
|
|
52949
|
+
|
|
52950
|
+
&:hover {
|
|
52951
|
+
filter: brightness(0.9);
|
|
52952
|
+
}
|
|
52953
|
+
}
|
|
52954
|
+
|
|
52955
|
+
td {
|
|
52956
|
+
text-align: right;
|
|
52957
|
+
}
|
|
52958
|
+
|
|
52959
|
+
th {
|
|
52960
|
+
background-color: #f5f5f5;
|
|
52961
|
+
font-weight: bold;
|
|
52962
|
+
color: black;
|
|
52963
|
+
}
|
|
52964
|
+
|
|
52965
|
+
.o_missing_value {
|
|
52966
|
+
color: #46646d;
|
|
52967
|
+
background: #e7f2f6;
|
|
52968
|
+
}
|
|
52969
|
+
}
|
|
52970
|
+
`;
|
|
52971
|
+
class PivotHTMLRenderer extends owl.Component {
|
|
52972
|
+
static template = "o_spreadsheet.PivotHTMLRenderer";
|
|
52973
|
+
static components = { Checkbox };
|
|
52974
|
+
static props = {
|
|
52975
|
+
pivotId: String,
|
|
52976
|
+
onCellClicked: Function,
|
|
52977
|
+
};
|
|
52978
|
+
pivot = this.env.model.getters.getPivot(this.props.pivotId);
|
|
52979
|
+
data = {
|
|
52980
|
+
columns: [],
|
|
52981
|
+
rows: [],
|
|
52982
|
+
values: [],
|
|
52983
|
+
};
|
|
52984
|
+
state = owl.useState({
|
|
52985
|
+
showMissingValuesOnly: false,
|
|
52986
|
+
});
|
|
52987
|
+
setup() {
|
|
52988
|
+
const table = this.pivot.getTableStructure();
|
|
52989
|
+
const formulaId = this.env.model.getters.getPivotFormulaId(this.props.pivotId);
|
|
52990
|
+
this.data = {
|
|
52991
|
+
columns: this._buildColHeaders(formulaId, table),
|
|
52992
|
+
rows: this._buildRowHeaders(formulaId, table),
|
|
52993
|
+
values: this._buildValues(formulaId, table),
|
|
52994
|
+
};
|
|
52995
|
+
}
|
|
52996
|
+
get tracker() {
|
|
52997
|
+
return this.env.model.getters.getPivotPresenceTracker(this.props.pivotId);
|
|
52998
|
+
}
|
|
52999
|
+
// ---------------------------------------------------------------------
|
|
53000
|
+
// Missing values building
|
|
53001
|
+
// ---------------------------------------------------------------------
|
|
53002
|
+
/**
|
|
53003
|
+
* Retrieve the data to display in the Pivot Table
|
|
53004
|
+
* In the case when showMissingValuesOnly is false, the returned value
|
|
53005
|
+
* is the complete data
|
|
53006
|
+
* In the case when showMissingValuesOnly is true, the returned value is
|
|
53007
|
+
* the data which contains only missing values in the rows and cols. In
|
|
53008
|
+
* the rows, we also return the parent rows of rows which contains missing
|
|
53009
|
+
* values, to give context to the user.
|
|
53010
|
+
*
|
|
53011
|
+
*/
|
|
53012
|
+
getTableData() {
|
|
53013
|
+
if (!this.state.showMissingValuesOnly) {
|
|
53014
|
+
return this.data;
|
|
53015
|
+
}
|
|
53016
|
+
const colIndexes = this.getColumnsIndexes();
|
|
53017
|
+
const rowIndexes = this.getRowsIndexes();
|
|
53018
|
+
const columns = this.buildColumnsMissing(colIndexes);
|
|
53019
|
+
const rows = this.buildRowsMissing(rowIndexes);
|
|
53020
|
+
const values = this.buildValuesMissing(colIndexes, rowIndexes);
|
|
53021
|
+
return { columns, rows, values };
|
|
53022
|
+
}
|
|
53023
|
+
/**
|
|
53024
|
+
* Retrieve the parents of the given row
|
|
53025
|
+
* ex:
|
|
53026
|
+
* Australia
|
|
53027
|
+
* January
|
|
53028
|
+
* February
|
|
53029
|
+
* The parent of "January" is "Australia"
|
|
53030
|
+
*/
|
|
53031
|
+
addRecursiveRow(index) {
|
|
53032
|
+
const rows = this.pivot.getTableStructure().rows;
|
|
53033
|
+
const row = [...rows[index].values];
|
|
53034
|
+
if (row.length <= 1) {
|
|
53035
|
+
return [index];
|
|
53036
|
+
}
|
|
53037
|
+
row.pop();
|
|
53038
|
+
const parentRowIndex = rows.findIndex((r) => JSON.stringify(r.values) === JSON.stringify(row));
|
|
53039
|
+
return [index].concat(this.addRecursiveRow(parentRowIndex));
|
|
53040
|
+
}
|
|
53041
|
+
/**
|
|
53042
|
+
* Create the columns to be used, based on the indexes of the columns in
|
|
53043
|
+
* which a missing value is present
|
|
53044
|
+
*
|
|
53045
|
+
*/
|
|
53046
|
+
buildColumnsMissing(indexes) {
|
|
53047
|
+
// columnsMap explode the columns in an array of array of the same
|
|
53048
|
+
// size with the index of each column, repeated 'span' times.
|
|
53049
|
+
// ex:
|
|
53050
|
+
// | A | B |
|
|
53051
|
+
// | 1 | 2 | 3 |
|
|
53052
|
+
// => [
|
|
53053
|
+
// [0, 0, 1]
|
|
53054
|
+
// [0, 1, 2]
|
|
53055
|
+
// ]
|
|
53056
|
+
const columnsMap = [];
|
|
53057
|
+
for (const column of this.data.columns) {
|
|
53058
|
+
const columnMap = [];
|
|
53059
|
+
for (const index in column) {
|
|
53060
|
+
for (let i = 0; i < column[index].span; i++) {
|
|
53061
|
+
columnMap.push(parseInt(index, 10));
|
|
53062
|
+
}
|
|
53063
|
+
}
|
|
53064
|
+
columnsMap.push(columnMap);
|
|
53065
|
+
}
|
|
53066
|
+
// Remove the columns that are not present in indexes
|
|
53067
|
+
for (let i = columnsMap[columnsMap.length - 1].length; i >= 0; i--) {
|
|
53068
|
+
if (!indexes.includes(i)) {
|
|
53069
|
+
for (const columnMap of columnsMap) {
|
|
53070
|
+
columnMap.splice(i, 1);
|
|
53071
|
+
}
|
|
53072
|
+
}
|
|
53073
|
+
}
|
|
53074
|
+
// Build the columns
|
|
53075
|
+
const columns = [];
|
|
53076
|
+
for (const mapIndex in columnsMap) {
|
|
53077
|
+
const column = [];
|
|
53078
|
+
let index = undefined;
|
|
53079
|
+
let span = 1;
|
|
53080
|
+
for (let i = 0; i < columnsMap[mapIndex].length; i++) {
|
|
53081
|
+
if (index !== columnsMap[mapIndex][i]) {
|
|
53082
|
+
if (index !== undefined) {
|
|
53083
|
+
column.push(Object.assign({}, this.data.columns[mapIndex][index], { span }));
|
|
53084
|
+
}
|
|
53085
|
+
index = columnsMap[mapIndex][i];
|
|
53086
|
+
span = 1;
|
|
53087
|
+
}
|
|
53088
|
+
else {
|
|
53089
|
+
span++;
|
|
53090
|
+
}
|
|
53091
|
+
}
|
|
53092
|
+
if (index !== undefined) {
|
|
53093
|
+
column.push(Object.assign({}, this.data.columns[mapIndex][index], { span }));
|
|
53094
|
+
}
|
|
53095
|
+
columns.push(column);
|
|
53096
|
+
}
|
|
53097
|
+
return columns;
|
|
53098
|
+
}
|
|
53099
|
+
/**
|
|
53100
|
+
* Create the rows to be used, based on the indexes of the rows in
|
|
53101
|
+
* which a missing value is present.
|
|
53102
|
+
*/
|
|
53103
|
+
buildRowsMissing(indexes) {
|
|
53104
|
+
return indexes.map((index) => this.data.rows[index]);
|
|
53105
|
+
}
|
|
53106
|
+
/**
|
|
53107
|
+
* Create the value to be used, based on the indexes of the columns and
|
|
53108
|
+
* rows in which a missing value is present.
|
|
53109
|
+
*/
|
|
53110
|
+
buildValuesMissing(colIndexes, rowIndexes) {
|
|
53111
|
+
const values = colIndexes.map(() => []);
|
|
53112
|
+
for (const row of rowIndexes) {
|
|
53113
|
+
for (const col in colIndexes) {
|
|
53114
|
+
values[col].push(this.data.values[colIndexes[col]][row]);
|
|
53115
|
+
}
|
|
53116
|
+
}
|
|
53117
|
+
return values;
|
|
53118
|
+
}
|
|
53119
|
+
getColumnsIndexes() {
|
|
53120
|
+
const indexes = new Set();
|
|
53121
|
+
for (let i = 0; i < this.data.columns.length; i++) {
|
|
53122
|
+
const exploded = [];
|
|
53123
|
+
for (let y = 0; y < this.data.columns[i].length; y++) {
|
|
53124
|
+
for (let x = 0; x < this.data.columns[i][y].span; x++) {
|
|
53125
|
+
exploded.push(this.data.columns[i][y]);
|
|
53126
|
+
}
|
|
53127
|
+
}
|
|
53128
|
+
for (let y = 0; y < exploded.length; y++) {
|
|
53129
|
+
if (exploded[y].isMissing) {
|
|
53130
|
+
indexes.add(y);
|
|
53131
|
+
}
|
|
53132
|
+
}
|
|
53133
|
+
}
|
|
53134
|
+
for (let i = 0; i < this.data.columns[this.data.columns.length - 1].length; i++) {
|
|
53135
|
+
const values = this.data.values[i];
|
|
53136
|
+
if (values.find((x) => x.isMissing)) {
|
|
53137
|
+
indexes.add(i);
|
|
53138
|
+
}
|
|
53139
|
+
}
|
|
53140
|
+
return Array.from(indexes).sort((a, b) => a - b);
|
|
53141
|
+
}
|
|
53142
|
+
getRowsIndexes() {
|
|
53143
|
+
const rowIndexes = new Set();
|
|
53144
|
+
for (let i = 0; i < this.data.rows.length; i++) {
|
|
53145
|
+
if (this.data.rows[i].isMissing) {
|
|
53146
|
+
rowIndexes.add(i);
|
|
53147
|
+
}
|
|
53148
|
+
for (const col of this.data.values) {
|
|
53149
|
+
if (col[i].isMissing) {
|
|
53150
|
+
this.addRecursiveRow(i).forEach((x) => rowIndexes.add(x));
|
|
53151
|
+
}
|
|
53152
|
+
}
|
|
53153
|
+
}
|
|
53154
|
+
return Array.from(rowIndexes).sort((a, b) => a - b);
|
|
53155
|
+
}
|
|
53156
|
+
// ---------------------------------------------------------------------
|
|
53157
|
+
// Data table creation
|
|
53158
|
+
// ---------------------------------------------------------------------
|
|
53159
|
+
_buildColHeaders(id, table) {
|
|
53160
|
+
const headers = [];
|
|
53161
|
+
for (const row of table.columns) {
|
|
53162
|
+
const current = [];
|
|
53163
|
+
for (const cell of row) {
|
|
53164
|
+
const args = [];
|
|
53165
|
+
for (let i = 0; i < cell.fields.length; i++) {
|
|
53166
|
+
args.push({ value: cell.fields[i] }, { value: cell.values[i] });
|
|
53167
|
+
}
|
|
53168
|
+
const domain = this.pivot.parseArgsToPivotDomain(args);
|
|
53169
|
+
const locale = this.env.model.getters.getLocale();
|
|
53170
|
+
if (domain.at(-1)?.field === "measure") {
|
|
53171
|
+
const { value, format } = this.pivot.getPivotMeasureValue(toString(domain.at(-1).value), domain);
|
|
53172
|
+
current.push({
|
|
53173
|
+
formula: `=PIVOT.HEADER(${generatePivotArgs(id, domain).join(",")})`,
|
|
53174
|
+
value: formatValue(value, { format, locale }),
|
|
53175
|
+
span: cell.width,
|
|
53176
|
+
isMissing: !this.tracker?.isHeaderPresent(domain),
|
|
53177
|
+
});
|
|
53178
|
+
}
|
|
53179
|
+
else {
|
|
53180
|
+
const { value, format } = this.pivot.getPivotHeaderValueAndFormat(domain);
|
|
53181
|
+
current.push({
|
|
53182
|
+
formula: `=PIVOT.HEADER(${generatePivotArgs(id, domain).join(",")})`,
|
|
53183
|
+
value: formatValue(value, { format, locale }),
|
|
53184
|
+
span: cell.width,
|
|
53185
|
+
isMissing: !this.tracker?.isHeaderPresent(domain),
|
|
53186
|
+
});
|
|
53187
|
+
}
|
|
53188
|
+
}
|
|
53189
|
+
headers.push(current);
|
|
53190
|
+
}
|
|
53191
|
+
const last = headers[headers.length - 1];
|
|
53192
|
+
headers[headers.length - 1] = last.map((cell) => {
|
|
53193
|
+
if (!cell.isMissing) {
|
|
53194
|
+
cell.style = "color: #756f6f;";
|
|
53195
|
+
}
|
|
53196
|
+
return cell;
|
|
53197
|
+
});
|
|
53198
|
+
return headers;
|
|
53199
|
+
}
|
|
53200
|
+
_buildRowHeaders(id, table) {
|
|
53201
|
+
const headers = [];
|
|
53202
|
+
for (const row of table.rows) {
|
|
53203
|
+
const args = [];
|
|
53204
|
+
for (let i = 0; i < row.fields.length; i++) {
|
|
53205
|
+
args.push({ value: row.fields[i] }, { value: row.values[i] });
|
|
53206
|
+
}
|
|
53207
|
+
const domain = this.pivot.parseArgsToPivotDomain(args);
|
|
53208
|
+
const { value, format } = this.pivot.getPivotHeaderValueAndFormat(domain);
|
|
53209
|
+
const locale = this.env.model.getters.getLocale();
|
|
53210
|
+
const cell = {
|
|
53211
|
+
formula: `=PIVOT.HEADER(${generatePivotArgs(id, domain).join(",")})`,
|
|
53212
|
+
value: formatValue(value, { format, locale }),
|
|
53213
|
+
isMissing: !this.tracker?.isHeaderPresent(domain),
|
|
53214
|
+
};
|
|
53215
|
+
if (row.indent > 1) {
|
|
53216
|
+
cell.style = `padding-left: ${row.indent - 1 * 10}px`;
|
|
53217
|
+
}
|
|
53218
|
+
headers.push(cell);
|
|
53219
|
+
}
|
|
53220
|
+
return headers;
|
|
53221
|
+
}
|
|
53222
|
+
_buildValues(id, table) {
|
|
53223
|
+
const values = [];
|
|
53224
|
+
for (const col of table.columns.at(-1) || []) {
|
|
53225
|
+
const current = [];
|
|
53226
|
+
const measure = toString(col.values[col.values.length - 1]);
|
|
53227
|
+
for (const row of table.rows) {
|
|
53228
|
+
const args = [];
|
|
53229
|
+
for (let i = 0; i < row.fields.length; i++) {
|
|
53230
|
+
args.push({ value: row.fields[i] }, { value: row.values[i] });
|
|
53231
|
+
}
|
|
53232
|
+
for (let i = 0; i < col.fields.length - 1; i++) {
|
|
53233
|
+
args.push({ value: col.fields[i] }, { value: col.values[i] });
|
|
53234
|
+
}
|
|
53235
|
+
const domain = this.pivot.parseArgsToPivotDomain(args);
|
|
53236
|
+
const { value, format } = this.pivot.getPivotCellValueAndFormat(measure, domain);
|
|
53237
|
+
const locale = this.env.model.getters.getLocale();
|
|
53238
|
+
current.push({
|
|
53239
|
+
formula: `=PIVOT.VALUE(${generatePivotArgs(id, domain, measure).join(",")})`,
|
|
53240
|
+
value: formatValue(value, { format, locale }),
|
|
53241
|
+
isMissing: !this.tracker?.isValuePresent(measure, domain),
|
|
53242
|
+
});
|
|
53243
|
+
}
|
|
53244
|
+
values.push(current);
|
|
53245
|
+
}
|
|
53246
|
+
return values;
|
|
53247
|
+
}
|
|
53248
|
+
}
|
|
53249
|
+
|
|
52772
53250
|
/**
|
|
52773
53251
|
* BasePlugin
|
|
52774
53252
|
*
|
|
@@ -54259,9 +54737,7 @@ class ChartPlugin extends CorePlugin {
|
|
|
54259
54737
|
: "Success" /* CommandResult.Success */;
|
|
54260
54738
|
}
|
|
54261
54739
|
checkChartExists(cmd) {
|
|
54262
|
-
return this.
|
|
54263
|
-
? "Success" /* CommandResult.Success */
|
|
54264
|
-
: "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
|
|
54740
|
+
return this.isChartDefined(cmd.id) ? "Success" /* CommandResult.Success */ : "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
|
|
54265
54741
|
}
|
|
54266
54742
|
}
|
|
54267
54743
|
|
|
@@ -56208,7 +56684,7 @@ class RangeAdapter {
|
|
|
56208
56684
|
if (range.sheetId === cmd.sheetId) {
|
|
56209
56685
|
return { changeType: "CHANGE", range };
|
|
56210
56686
|
}
|
|
56211
|
-
if (
|
|
56687
|
+
if (isSheetNameEqual(range.invalidSheetName, cmd.name)) {
|
|
56212
56688
|
const invalidSheetName = undefined;
|
|
56213
56689
|
const sheetId = cmd.sheetId;
|
|
56214
56690
|
const newRange = range.clone({ sheetId, invalidSheetName });
|
|
@@ -56546,6 +57022,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
56546
57022
|
"getCommandZones",
|
|
56547
57023
|
"getUnboundedZone",
|
|
56548
57024
|
"checkElementsIncludeAllNonFrozenHeaders",
|
|
57025
|
+
"getDuplicateSheetName",
|
|
56549
57026
|
];
|
|
56550
57027
|
sheetIdsMapName = {};
|
|
56551
57028
|
orderedSheetIds = [];
|
|
@@ -56570,7 +57047,11 @@ class SheetPlugin extends CorePlugin {
|
|
|
56570
57047
|
return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
|
|
56571
57048
|
}
|
|
56572
57049
|
case "DUPLICATE_SHEET": {
|
|
56573
|
-
|
|
57050
|
+
if (this.sheets[cmd.sheetIdTo])
|
|
57051
|
+
return "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */;
|
|
57052
|
+
if (this.orderedSheetIds.map(this.getSheetName.bind(this)).includes(cmd.sheetNameTo))
|
|
57053
|
+
return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
|
|
57054
|
+
return "Success" /* CommandResult.Success */;
|
|
56574
57055
|
}
|
|
56575
57056
|
case "MOVE_SHEET":
|
|
56576
57057
|
try {
|
|
@@ -56647,7 +57128,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
56647
57128
|
this.showSheet(cmd.sheetId);
|
|
56648
57129
|
break;
|
|
56649
57130
|
case "DUPLICATE_SHEET":
|
|
56650
|
-
this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo);
|
|
57131
|
+
this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo, cmd.sheetNameTo);
|
|
56651
57132
|
break;
|
|
56652
57133
|
case "DELETE_SHEET":
|
|
56653
57134
|
this.deleteSheet(this.sheets[cmd.sheetId]);
|
|
@@ -56788,7 +57269,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
56788
57269
|
if (name) {
|
|
56789
57270
|
const unquotedName = getUnquotedSheetName(name);
|
|
56790
57271
|
for (const key in this.sheetIdsMapName) {
|
|
56791
|
-
if (key
|
|
57272
|
+
if (isSheetNameEqual(key, unquotedName)) {
|
|
56792
57273
|
return this.sheetIdsMapName[key];
|
|
56793
57274
|
}
|
|
56794
57275
|
}
|
|
@@ -56853,14 +57334,8 @@ class SheetPlugin extends CorePlugin {
|
|
|
56853
57334
|
return dimension === "COL" ? this.getNumberCols(sheetId) : this.getNumberRows(sheetId);
|
|
56854
57335
|
}
|
|
56855
57336
|
getNextSheetName(baseName = "Sheet") {
|
|
56856
|
-
let i = 1;
|
|
56857
57337
|
const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
|
|
56858
|
-
|
|
56859
|
-
while (names.includes(name)) {
|
|
56860
|
-
name = `${baseName}${i}`;
|
|
56861
|
-
i++;
|
|
56862
|
-
}
|
|
56863
|
-
return name;
|
|
57338
|
+
return getNextSheetName(names, baseName);
|
|
56864
57339
|
}
|
|
56865
57340
|
getSheetSize(sheetId) {
|
|
56866
57341
|
return {
|
|
@@ -57042,7 +57517,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
57042
57517
|
}
|
|
57043
57518
|
const { orderedSheetIds, sheets } = this;
|
|
57044
57519
|
const name = cmd.name && cmd.name.trim().toLowerCase();
|
|
57045
|
-
if (orderedSheetIds.find((id) => sheets[id]?.name
|
|
57520
|
+
if (orderedSheetIds.find((id) => isSheetNameEqual(sheets[id]?.name, name) && id !== cmd.sheetId)) {
|
|
57046
57521
|
return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
|
|
57047
57522
|
}
|
|
57048
57523
|
if (FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX.test(name)) {
|
|
@@ -57106,9 +57581,8 @@ class SheetPlugin extends CorePlugin {
|
|
|
57106
57581
|
showSheet(sheetId) {
|
|
57107
57582
|
this.history.update("sheets", sheetId, "isVisible", true);
|
|
57108
57583
|
}
|
|
57109
|
-
duplicateSheet(fromId, toId) {
|
|
57584
|
+
duplicateSheet(fromId, toId, toName) {
|
|
57110
57585
|
const sheet = this.getSheet(fromId);
|
|
57111
|
-
const toName = this.getDuplicateSheetName(sheet.name);
|
|
57112
57586
|
const newSheet = deepCopy(sheet);
|
|
57113
57587
|
newSheet.id = toId;
|
|
57114
57588
|
newSheet.name = toName;
|
|
@@ -57140,15 +57614,8 @@ class SheetPlugin extends CorePlugin {
|
|
|
57140
57614
|
this.history.update("sheetIdsMapName", sheetIdsMapName);
|
|
57141
57615
|
}
|
|
57142
57616
|
getDuplicateSheetName(sheetName) {
|
|
57143
|
-
let i = 1;
|
|
57144
57617
|
const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
|
|
57145
|
-
|
|
57146
|
-
let name = baseName.toString();
|
|
57147
|
-
while (names.includes(name)) {
|
|
57148
|
-
name = `${baseName} (${i})`;
|
|
57149
|
-
i++;
|
|
57150
|
-
}
|
|
57151
|
-
return name;
|
|
57618
|
+
return getDuplicateSheetName(sheetName, names);
|
|
57152
57619
|
}
|
|
57153
57620
|
deleteSheet(sheet) {
|
|
57154
57621
|
const name = sheet.name;
|
|
@@ -59975,8 +60442,8 @@ class SpreadingRelation {
|
|
|
59975
60442
|
const EMPTY_ARRAY = [];
|
|
59976
60443
|
|
|
59977
60444
|
const MAX_ITERATION = 30;
|
|
59978
|
-
const ERROR_CYCLE_CELL = createEvaluatedCell(new CircularDependencyError());
|
|
59979
|
-
const EMPTY_CELL = createEvaluatedCell({ value: null });
|
|
60445
|
+
const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell(new CircularDependencyError()));
|
|
60446
|
+
const EMPTY_CELL = Object.freeze(createEvaluatedCell({ value: null }));
|
|
59980
60447
|
class Evaluator {
|
|
59981
60448
|
context;
|
|
59982
60449
|
getters;
|
|
@@ -65953,6 +66420,55 @@ class HistoryPlugin extends UIPlugin {
|
|
|
65953
66420
|
}
|
|
65954
66421
|
}
|
|
65955
66422
|
|
|
66423
|
+
class PivotPresenceTracker {
|
|
66424
|
+
trackedValues = new Set();
|
|
66425
|
+
domainToArray(domain) {
|
|
66426
|
+
return domain.flatMap((node) => [node.field, toString(node.value)]);
|
|
66427
|
+
}
|
|
66428
|
+
isValuePresent(measure, domain) {
|
|
66429
|
+
const key = JSON.stringify({ measure, domain: this.domainToArray(domain) });
|
|
66430
|
+
return this.trackedValues.has(key);
|
|
66431
|
+
}
|
|
66432
|
+
isHeaderPresent(domain) {
|
|
66433
|
+
const key = JSON.stringify({ domain: this.domainToArray(domain) });
|
|
66434
|
+
return this.trackedValues.has(key);
|
|
66435
|
+
}
|
|
66436
|
+
trackValue(measure, domain) {
|
|
66437
|
+
const key = JSON.stringify({ measure, domain: this.domainToArray(domain) });
|
|
66438
|
+
this.trackedValues.add(key);
|
|
66439
|
+
}
|
|
66440
|
+
trackHeader(domain) {
|
|
66441
|
+
const key = JSON.stringify({ domain: this.domainToArray(domain) });
|
|
66442
|
+
this.trackedValues.add(key);
|
|
66443
|
+
}
|
|
66444
|
+
}
|
|
66445
|
+
|
|
66446
|
+
class PivotPresencePlugin extends UIPlugin {
|
|
66447
|
+
static getters = ["getPivotPresenceTracker"];
|
|
66448
|
+
trackPresencePivotId;
|
|
66449
|
+
tracker;
|
|
66450
|
+
handle(cmd) {
|
|
66451
|
+
switch (cmd.type) {
|
|
66452
|
+
case "PIVOT_START_PRESENCE_TRACKING":
|
|
66453
|
+
this.tracker = new PivotPresenceTracker();
|
|
66454
|
+
this.trackPresencePivotId = cmd.pivotId;
|
|
66455
|
+
break;
|
|
66456
|
+
case "PIVOT_STOP_PRESENCE_TRACKING":
|
|
66457
|
+
this.trackPresencePivotId = undefined;
|
|
66458
|
+
break;
|
|
66459
|
+
}
|
|
66460
|
+
}
|
|
66461
|
+
getPivotPresenceTracker(pivotId) {
|
|
66462
|
+
if (this.trackPresencePivotId !== pivotId) {
|
|
66463
|
+
return undefined;
|
|
66464
|
+
}
|
|
66465
|
+
if (!this.tracker) {
|
|
66466
|
+
throw new Error("Tracker not initialized");
|
|
66467
|
+
}
|
|
66468
|
+
return this.tracker;
|
|
66469
|
+
}
|
|
66470
|
+
}
|
|
66471
|
+
|
|
65956
66472
|
class SplitToColumnsPlugin extends UIPlugin {
|
|
65957
66473
|
static getters = ["getAutomaticSeparator"];
|
|
65958
66474
|
allowDispatch(cmd) {
|
|
@@ -68740,6 +69256,7 @@ const featurePluginRegistry = new Registry()
|
|
|
68740
69256
|
.add("automatic_sum", AutomaticSumPlugin)
|
|
68741
69257
|
.add("format", FormatPlugin)
|
|
68742
69258
|
.add("insert_pivot", InsertPivotPlugin)
|
|
69259
|
+
.add("pivot_presence", PivotPresencePlugin)
|
|
68743
69260
|
.add("split_to_columns", SplitToColumnsPlugin)
|
|
68744
69261
|
.add("collaborative", CollaborativePlugin)
|
|
68745
69262
|
.add("history", HistoryPlugin)
|
|
@@ -69120,11 +69637,11 @@ class BottomBarSheet extends owl.Component {
|
|
|
69120
69637
|
if (ev.key === "Enter") {
|
|
69121
69638
|
ev.preventDefault();
|
|
69122
69639
|
this.stopEdition();
|
|
69123
|
-
this.DOMFocusableElementStore.
|
|
69640
|
+
this.DOMFocusableElementStore.focus();
|
|
69124
69641
|
}
|
|
69125
69642
|
if (ev.key === "Escape") {
|
|
69126
69643
|
this.cancelEdition();
|
|
69127
|
-
this.DOMFocusableElementStore.
|
|
69644
|
+
this.DOMFocusableElementStore.focus();
|
|
69128
69645
|
}
|
|
69129
69646
|
}
|
|
69130
69647
|
onMouseEventSheetName(ev) {
|
|
@@ -71308,11 +71825,13 @@ class Spreadsheet extends owl.Component {
|
|
|
71308
71825
|
this.checkViewportSize();
|
|
71309
71826
|
stores.on("store-updated", this, render);
|
|
71310
71827
|
resizeObserver.observe(this.spreadsheetRef.el);
|
|
71828
|
+
registerChartJSExtensions();
|
|
71311
71829
|
});
|
|
71312
71830
|
owl.onWillUnmount(() => {
|
|
71313
71831
|
this.unbindModelEvents();
|
|
71314
71832
|
stores.off("store-updated", this);
|
|
71315
71833
|
resizeObserver.disconnect();
|
|
71834
|
+
unregisterChartJsExtensions();
|
|
71316
71835
|
});
|
|
71317
71836
|
owl.onPatched(() => {
|
|
71318
71837
|
this.checkViewportSize();
|
|
@@ -75713,6 +76232,7 @@ const components = {
|
|
|
75713
76232
|
PivotDimensionOrder,
|
|
75714
76233
|
PivotDimension,
|
|
75715
76234
|
PivotLayoutConfigurator,
|
|
76235
|
+
PivotHTMLRenderer,
|
|
75716
76236
|
PivotDeferUpdate,
|
|
75717
76237
|
PivotTitleSection,
|
|
75718
76238
|
CogWheelMenu,
|
|
@@ -75806,6 +76326,6 @@ exports.tokenColors = tokenColors;
|
|
|
75806
76326
|
exports.tokenize = tokenize;
|
|
75807
76327
|
|
|
75808
76328
|
|
|
75809
|
-
__info__.version = "18.1.
|
|
75810
|
-
__info__.date = "2025-05-
|
|
75811
|
-
__info__.hash = "
|
|
76329
|
+
__info__.version = "18.1.20";
|
|
76330
|
+
__info__.date = "2025-05-13T17:52:28.174Z";
|
|
76331
|
+
__info__.hash = "3e43a46";
|