@odoo/o-spreadsheet 18.2.10 → 18.2.12
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 +624 -90
- package/dist/o-spreadsheet.d.ts +289 -159
- package/dist/o-spreadsheet.esm.js +624 -90
- package/dist/o-spreadsheet.iife.js +624 -90
- package/dist/o-spreadsheet.iife.min.js +428 -392
- 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.2.
|
|
6
|
-
* @date 2025-05-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.2.12
|
|
6
|
+
* @date 2025-05-13T17:52:23.989Z
|
|
7
|
+
* @hash ba2ba9b
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -3359,7 +3359,7 @@ function isDateAfter(date, dateAfter) {
|
|
|
3359
3359
|
*/
|
|
3360
3360
|
const getFormulaNumberRegex = memoize(function getFormulaNumberRegex(decimalSeparator) {
|
|
3361
3361
|
decimalSeparator = escapeRegExp(decimalSeparator);
|
|
3362
|
-
return new RegExp(`(?:^-?\\d+(?:${decimalSeparator}?\\d*(?:e
|
|
3362
|
+
return new RegExp(`(?:^-?\\d+(?:${decimalSeparator}?\\d*(?:e(\\+|-)?\\d+)?)?|^-?${decimalSeparator}\\d+)(?!\\w|!)`);
|
|
3363
3363
|
});
|
|
3364
3364
|
const getNumberRegex = memoize(function getNumberRegex(locale) {
|
|
3365
3365
|
const decimalSeparator = escapeRegExp(locale.decimalSeparator);
|
|
@@ -6282,6 +6282,32 @@ function moveHeaderIndexesOnHeaderDeletion(deletedHeaders, headers) {
|
|
|
6282
6282
|
})
|
|
6283
6283
|
.filter(isDefined);
|
|
6284
6284
|
}
|
|
6285
|
+
function getNextSheetName(existingNames, baseName = "Sheet") {
|
|
6286
|
+
let i = 1;
|
|
6287
|
+
let name = `${baseName}${i}`;
|
|
6288
|
+
while (existingNames.includes(name)) {
|
|
6289
|
+
name = `${baseName}${i}`;
|
|
6290
|
+
i++;
|
|
6291
|
+
}
|
|
6292
|
+
return name;
|
|
6293
|
+
}
|
|
6294
|
+
function getDuplicateSheetName(nameToDuplicate, existingNames) {
|
|
6295
|
+
let i = 1;
|
|
6296
|
+
const baseName = _t("Copy of %s", nameToDuplicate);
|
|
6297
|
+
let name = baseName.toString();
|
|
6298
|
+
while (existingNames.includes(name)) {
|
|
6299
|
+
name = `${baseName} (${i})`;
|
|
6300
|
+
i++;
|
|
6301
|
+
}
|
|
6302
|
+
return name;
|
|
6303
|
+
}
|
|
6304
|
+
function isSheetNameEqual(name1, name2) {
|
|
6305
|
+
if (name1 === undefined || name2 === undefined) {
|
|
6306
|
+
return false;
|
|
6307
|
+
}
|
|
6308
|
+
return (getUnquotedSheetName(name1.trim().toUpperCase()) ===
|
|
6309
|
+
getUnquotedSheetName(name2.trim().toUpperCase()));
|
|
6310
|
+
}
|
|
6285
6311
|
|
|
6286
6312
|
function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
|
|
6287
6313
|
return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
|
|
@@ -7980,6 +8006,24 @@ const monthNumberAdapter = {
|
|
|
7980
8006
|
return `${normalizedValue}`;
|
|
7981
8007
|
},
|
|
7982
8008
|
};
|
|
8009
|
+
/**
|
|
8010
|
+
* normalizes month number + year
|
|
8011
|
+
*/
|
|
8012
|
+
const monthAdapter = {
|
|
8013
|
+
normalizeFunctionValue(value) {
|
|
8014
|
+
const date = toNumber(value, DEFAULT_LOCALE);
|
|
8015
|
+
return formatValue(date, { locale: DEFAULT_LOCALE, format: "mm/yyyy" });
|
|
8016
|
+
},
|
|
8017
|
+
toValueAndFormat(normalizedValue) {
|
|
8018
|
+
return {
|
|
8019
|
+
value: toNumber(normalizedValue, DEFAULT_LOCALE),
|
|
8020
|
+
format: "mmmm yyyy",
|
|
8021
|
+
};
|
|
8022
|
+
},
|
|
8023
|
+
toFunctionValue(normalizedValue) {
|
|
8024
|
+
return `"${normalizedValue}"`;
|
|
8025
|
+
},
|
|
8026
|
+
};
|
|
7983
8027
|
/**
|
|
7984
8028
|
* normalizes quarter number
|
|
7985
8029
|
*/
|
|
@@ -8110,6 +8154,7 @@ pivotTimeAdapterRegistry
|
|
|
8110
8154
|
.add("day_of_month", nullHandlerDecorator(dayOfMonthAdapter))
|
|
8111
8155
|
.add("iso_week_number", nullHandlerDecorator(isoWeekNumberAdapter))
|
|
8112
8156
|
.add("month_number", nullHandlerDecorator(monthNumberAdapter))
|
|
8157
|
+
.add("month", nullHandlerDecorator(monthAdapter))
|
|
8113
8158
|
.add("quarter_number", nullHandlerDecorator(quarterNumberAdapter))
|
|
8114
8159
|
.add("day_of_week", nullHandlerDecorator(dayOfWeekAdapter))
|
|
8115
8160
|
.add("hour_number", nullHandlerDecorator(hourNumberAdapter))
|
|
@@ -8126,10 +8171,9 @@ const AGGREGATOR_NAMES = {
|
|
|
8126
8171
|
avg: _t("Average"),
|
|
8127
8172
|
sum: _t("Sum"),
|
|
8128
8173
|
};
|
|
8129
|
-
const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
|
|
8130
8174
|
const AGGREGATORS_BY_FIELD_TYPE = {
|
|
8131
|
-
integer:
|
|
8132
|
-
char:
|
|
8175
|
+
integer: ["max", "min", "avg", "sum", "count_distinct", "count"],
|
|
8176
|
+
char: ["count_distinct", "count"],
|
|
8133
8177
|
boolean: ["count_distinct", "count", "bool_and", "bool_or"],
|
|
8134
8178
|
datetime: ["max", "min", "count_distinct", "count"],
|
|
8135
8179
|
};
|
|
@@ -8290,10 +8334,7 @@ function toNormalizedPivotValue(dimension, groupValue) {
|
|
|
8290
8334
|
return normalizer(groupValueString, dimension.granularity);
|
|
8291
8335
|
}
|
|
8292
8336
|
function normalizeDateTime(value, granularity) {
|
|
8293
|
-
|
|
8294
|
-
throw new Error("Missing granularity");
|
|
8295
|
-
}
|
|
8296
|
-
return pivotTimeAdapter(granularity).normalizeFunctionValue(value);
|
|
8337
|
+
return pivotTimeAdapter(granularity ?? "month").normalizeFunctionValue(value);
|
|
8297
8338
|
}
|
|
8298
8339
|
function toFunctionPivotValue(value, dimension) {
|
|
8299
8340
|
if (value === null) {
|
|
@@ -8305,10 +8346,7 @@ function toFunctionPivotValue(value, dimension) {
|
|
|
8305
8346
|
return pivotToFunctionValueRegistry.get(dimension.type)(value, dimension.granularity);
|
|
8306
8347
|
}
|
|
8307
8348
|
function toFunctionValueDateTime(value, granularity) {
|
|
8308
|
-
|
|
8309
|
-
throw new Error("Missing granularity");
|
|
8310
|
-
}
|
|
8311
|
-
return pivotTimeAdapter(granularity).toFunctionValue(value);
|
|
8349
|
+
return pivotTimeAdapter(granularity ?? "month").toFunctionValue(value);
|
|
8312
8350
|
}
|
|
8313
8351
|
const pivotNormalizationValueRegistry = new Registry();
|
|
8314
8352
|
pivotNormalizationValueRegistry
|
|
@@ -9488,7 +9526,10 @@ function proxifyStoreMutation(store, callback) {
|
|
|
9488
9526
|
const functionProxy = new Proxy(value, {
|
|
9489
9527
|
// trap the function call
|
|
9490
9528
|
apply(target, thisArg, argArray) {
|
|
9491
|
-
Reflect.apply(target, thisStore, argArray);
|
|
9529
|
+
const res = Reflect.apply(target, thisStore, argArray);
|
|
9530
|
+
if (res === "noStateChange") {
|
|
9531
|
+
return;
|
|
9532
|
+
}
|
|
9492
9533
|
callback();
|
|
9493
9534
|
},
|
|
9494
9535
|
});
|
|
@@ -9510,7 +9551,7 @@ function getDependencyContainer(env) {
|
|
|
9510
9551
|
const ModelStore = createAbstractStore("Model");
|
|
9511
9552
|
|
|
9512
9553
|
class RendererStore {
|
|
9513
|
-
mutators = ["register", "unRegister"];
|
|
9554
|
+
mutators = ["register", "unRegister", "drawLayer"];
|
|
9514
9555
|
renderers = {};
|
|
9515
9556
|
register(renderer) {
|
|
9516
9557
|
if (!renderer.renderingLayers.length) {
|
|
@@ -9530,14 +9571,14 @@ class RendererStore {
|
|
|
9530
9571
|
}
|
|
9531
9572
|
drawLayer(context, layer) {
|
|
9532
9573
|
const renderers = this.renderers[layer];
|
|
9533
|
-
if (
|
|
9534
|
-
|
|
9535
|
-
|
|
9536
|
-
|
|
9537
|
-
|
|
9538
|
-
|
|
9539
|
-
context.ctx.restore();
|
|
9574
|
+
if (renderers) {
|
|
9575
|
+
for (const renderer of renderers) {
|
|
9576
|
+
context.ctx.save();
|
|
9577
|
+
renderer.drawLayer(context, layer);
|
|
9578
|
+
context.ctx.restore();
|
|
9579
|
+
}
|
|
9540
9580
|
}
|
|
9581
|
+
return "noStateChange";
|
|
9541
9582
|
}
|
|
9542
9583
|
}
|
|
9543
9584
|
|
|
@@ -9590,16 +9631,17 @@ class ComposerFocusStore extends SpreadsheetStore {
|
|
|
9590
9631
|
focusComposer(listener, args) {
|
|
9591
9632
|
this.activeComposer = listener;
|
|
9592
9633
|
if (this.getters.isReadonly()) {
|
|
9593
|
-
return;
|
|
9634
|
+
return "noStateChange";
|
|
9594
9635
|
}
|
|
9595
9636
|
this._focusMode = args.focusMode || "contentFocus";
|
|
9596
9637
|
if (this._focusMode !== "inactive") {
|
|
9597
9638
|
this.setComposerContent(args);
|
|
9598
9639
|
}
|
|
9640
|
+
return;
|
|
9599
9641
|
}
|
|
9600
9642
|
focusActiveComposer(args) {
|
|
9601
9643
|
if (this.getters.isReadonly()) {
|
|
9602
|
-
return;
|
|
9644
|
+
return "noStateChange";
|
|
9603
9645
|
}
|
|
9604
9646
|
if (!this.activeComposer) {
|
|
9605
9647
|
throw new Error("No composer is registered");
|
|
@@ -9608,6 +9650,7 @@ class ComposerFocusStore extends SpreadsheetStore {
|
|
|
9608
9650
|
if (this._focusMode !== "inactive") {
|
|
9609
9651
|
this.setComposerContent(args);
|
|
9610
9652
|
}
|
|
9653
|
+
return;
|
|
9611
9654
|
}
|
|
9612
9655
|
/**
|
|
9613
9656
|
* Start the edition or update the content if it's already started.
|
|
@@ -9767,12 +9810,24 @@ function getElementMargins(el) {
|
|
|
9767
9810
|
}
|
|
9768
9811
|
|
|
9769
9812
|
const chartJsExtensionRegistry = new Registry();
|
|
9770
|
-
|
|
9771
|
-
|
|
9772
|
-
|
|
9773
|
-
|
|
9813
|
+
function areChartJSExtensionsLoaded() {
|
|
9814
|
+
return !!window.Chart.registry.plugins.get("chartShowValuesPlugin");
|
|
9815
|
+
}
|
|
9816
|
+
function registerChartJSExtensions() {
|
|
9817
|
+
if (!window.Chart || areChartJSExtensionsLoaded()) {
|
|
9818
|
+
return;
|
|
9819
|
+
}
|
|
9820
|
+
for (const registryItem of chartJsExtensionRegistry.getAll()) {
|
|
9821
|
+
registryItem.register(window.Chart);
|
|
9822
|
+
}
|
|
9823
|
+
}
|
|
9824
|
+
function unregisterChartJsExtensions() {
|
|
9825
|
+
if (!window.Chart) {
|
|
9826
|
+
return;
|
|
9827
|
+
}
|
|
9828
|
+
for (const registryItem of chartJsExtensionRegistry.getAll()) {
|
|
9829
|
+
registryItem.unregister(window.Chart);
|
|
9774
9830
|
}
|
|
9775
|
-
return window.Chart;
|
|
9776
9831
|
}
|
|
9777
9832
|
|
|
9778
9833
|
const TREND_LINE_XAXIS_ID = "x1";
|
|
@@ -10089,7 +10144,7 @@ function getDefinedAxis(definition) {
|
|
|
10089
10144
|
}
|
|
10090
10145
|
function formatChartDatasetValue(axisFormats, locale) {
|
|
10091
10146
|
return (value, axisId) => {
|
|
10092
|
-
const format =
|
|
10147
|
+
const format = axisFormats?.[axisId];
|
|
10093
10148
|
return formatTickValue({ format, locale })(value);
|
|
10094
10149
|
};
|
|
10095
10150
|
}
|
|
@@ -10263,7 +10318,7 @@ function drawPieChartValues(chart, options, ctx) {
|
|
|
10263
10318
|
const y = bar.y + midRadius * Math.sin(midAngle) + 7;
|
|
10264
10319
|
ctx.fillStyle = chartFontColor(options.background);
|
|
10265
10320
|
ctx.strokeStyle = options.background || "#ffffff";
|
|
10266
|
-
const displayValue = options.callback(value);
|
|
10321
|
+
const displayValue = options.callback(value, "y");
|
|
10267
10322
|
drawTextWithBackground(displayValue, x, y, ctx);
|
|
10268
10323
|
}
|
|
10269
10324
|
}
|
|
@@ -10332,8 +10387,14 @@ css /* scss */ `
|
|
|
10332
10387
|
}
|
|
10333
10388
|
}
|
|
10334
10389
|
`;
|
|
10335
|
-
chartJsExtensionRegistry.add("chartShowValuesPlugin",
|
|
10336
|
-
|
|
10390
|
+
chartJsExtensionRegistry.add("chartShowValuesPlugin", {
|
|
10391
|
+
register: (Chart) => Chart.register(chartShowValuesPlugin),
|
|
10392
|
+
unregister: (Chart) => Chart.unregister(chartShowValuesPlugin),
|
|
10393
|
+
});
|
|
10394
|
+
chartJsExtensionRegistry.add("waterfallLinesPlugin", {
|
|
10395
|
+
register: (Chart) => Chart.register(waterfallLinesPlugin),
|
|
10396
|
+
unregister: (Chart) => Chart.unregister(waterfallLinesPlugin),
|
|
10397
|
+
});
|
|
10337
10398
|
class ChartJsComponent extends owl.Component {
|
|
10338
10399
|
static template = "o-spreadsheet-ChartJsComponent";
|
|
10339
10400
|
static props = {
|
|
@@ -10385,8 +10446,7 @@ class ChartJsComponent extends owl.Component {
|
|
|
10385
10446
|
createChart(chartData) {
|
|
10386
10447
|
const canvas = this.canvas.el;
|
|
10387
10448
|
const ctx = canvas.getContext("2d");
|
|
10388
|
-
|
|
10389
|
-
this.chart = new Chart(ctx, chartData);
|
|
10449
|
+
this.chart = new window.Chart(ctx, chartData);
|
|
10390
10450
|
}
|
|
10391
10451
|
updateChartJs(chartData) {
|
|
10392
10452
|
if (chartData.data && chartData.data.datasets) {
|
|
@@ -18518,7 +18578,7 @@ const IF = {
|
|
|
18518
18578
|
return { value: "" };
|
|
18519
18579
|
}
|
|
18520
18580
|
if (result.value === null) {
|
|
18521
|
-
result
|
|
18581
|
+
return { ...result, value: "" };
|
|
18522
18582
|
}
|
|
18523
18583
|
return result;
|
|
18524
18584
|
},
|
|
@@ -18539,7 +18599,7 @@ const IFERROR = {
|
|
|
18539
18599
|
return { value: "" };
|
|
18540
18600
|
}
|
|
18541
18601
|
if (result.value === null) {
|
|
18542
|
-
result
|
|
18602
|
+
return { ...result, value: "" };
|
|
18543
18603
|
}
|
|
18544
18604
|
return result;
|
|
18545
18605
|
},
|
|
@@ -18560,7 +18620,7 @@ const IFNA = {
|
|
|
18560
18620
|
return { value: "" };
|
|
18561
18621
|
}
|
|
18562
18622
|
if (result.value === null) {
|
|
18563
|
-
result
|
|
18623
|
+
return { ...result, value: "" };
|
|
18564
18624
|
}
|
|
18565
18625
|
return result;
|
|
18566
18626
|
},
|
|
@@ -18586,7 +18646,7 @@ const IFS = {
|
|
|
18586
18646
|
return { value: "" };
|
|
18587
18647
|
}
|
|
18588
18648
|
if (result.value === null) {
|
|
18589
|
-
result
|
|
18649
|
+
return { ...result, value: "" };
|
|
18590
18650
|
}
|
|
18591
18651
|
return result;
|
|
18592
18652
|
}
|
|
@@ -18704,6 +18764,11 @@ function addPivotDependencies(evalContext, coreDefinition, forMeasures) {
|
|
|
18704
18764
|
if (range === undefined || range.invalidXc || range.invalidSheetName) {
|
|
18705
18765
|
throw new InvalidReferenceError();
|
|
18706
18766
|
}
|
|
18767
|
+
if (evalContext.__originCellPosition &&
|
|
18768
|
+
range.sheetId === evalContext.__originSheetId &&
|
|
18769
|
+
isZoneInside(positionToZone(evalContext.__originCellPosition), zone)) {
|
|
18770
|
+
throw new CircularDependencyError();
|
|
18771
|
+
}
|
|
18707
18772
|
dependencies.push(range);
|
|
18708
18773
|
}
|
|
18709
18774
|
for (const measure of forMeasures) {
|
|
@@ -19152,6 +19217,9 @@ const PIVOT_VALUE = {
|
|
|
19152
19217
|
};
|
|
19153
19218
|
}
|
|
19154
19219
|
const domain = pivot.parseArgsToPivotDomain(domainArgs);
|
|
19220
|
+
if (this.getters.getActiveSheetId() === this.__originSheetId) {
|
|
19221
|
+
this.getters.getPivotPresenceTracker(pivotId)?.trackValue(_measure, domain);
|
|
19222
|
+
}
|
|
19155
19223
|
return pivot.getPivotCellValueAndFormat(_measure, domain);
|
|
19156
19224
|
},
|
|
19157
19225
|
};
|
|
@@ -19183,6 +19251,9 @@ const PIVOT_HEADER = {
|
|
|
19183
19251
|
};
|
|
19184
19252
|
}
|
|
19185
19253
|
const domain = pivot.parseArgsToPivotDomain(domainArgs);
|
|
19254
|
+
if (this.getters.getActiveSheetId() === this.__originSheetId) {
|
|
19255
|
+
this.getters.getPivotPresenceTracker(_pivotId)?.trackHeader(domain);
|
|
19256
|
+
}
|
|
19186
19257
|
const lastNode = domain.at(-1);
|
|
19187
19258
|
if (lastNode?.field === "measure") {
|
|
19188
19259
|
return pivot.getPivotMeasureValue(toString(lastNode.value), domain);
|
|
@@ -19405,6 +19476,9 @@ function isEmpty(data) {
|
|
|
19405
19476
|
return data === undefined || data.value === null;
|
|
19406
19477
|
}
|
|
19407
19478
|
const getNeutral = { number: 0, string: "", boolean: false };
|
|
19479
|
+
function areAlmostEqual(value1, value2, epsilon = 2e-16) {
|
|
19480
|
+
return Math.abs(value1 - value2) < epsilon;
|
|
19481
|
+
}
|
|
19408
19482
|
const EQ = {
|
|
19409
19483
|
description: _t("Equal."),
|
|
19410
19484
|
args: [
|
|
@@ -19426,6 +19500,9 @@ const EQ = {
|
|
|
19426
19500
|
if (typeof _value2 === "string") {
|
|
19427
19501
|
_value2 = _value2.toUpperCase();
|
|
19428
19502
|
}
|
|
19503
|
+
if (typeof _value1 === "number" && typeof _value2 === "number") {
|
|
19504
|
+
return { value: areAlmostEqual(_value1, _value2) };
|
|
19505
|
+
}
|
|
19429
19506
|
return { value: _value1 === _value2 };
|
|
19430
19507
|
},
|
|
19431
19508
|
};
|
|
@@ -19465,6 +19542,9 @@ const GT = {
|
|
|
19465
19542
|
],
|
|
19466
19543
|
compute: function (value1, value2) {
|
|
19467
19544
|
return applyRelationalOperator(value1, value2, (v1, v2) => {
|
|
19545
|
+
if (typeof v1 === "number" && typeof v2 === "number") {
|
|
19546
|
+
return !areAlmostEqual(v1, v2) && v1 > v2;
|
|
19547
|
+
}
|
|
19468
19548
|
return v1 > v2;
|
|
19469
19549
|
});
|
|
19470
19550
|
},
|
|
@@ -19480,6 +19560,9 @@ const GTE = {
|
|
|
19480
19560
|
],
|
|
19481
19561
|
compute: function (value1, value2) {
|
|
19482
19562
|
return applyRelationalOperator(value1, value2, (v1, v2) => {
|
|
19563
|
+
if (typeof v1 === "number" && typeof v2 === "number") {
|
|
19564
|
+
return areAlmostEqual(v1, v2) || v1 > v2;
|
|
19565
|
+
}
|
|
19483
19566
|
return v1 >= v2;
|
|
19484
19567
|
});
|
|
19485
19568
|
},
|
|
@@ -21086,7 +21169,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
21086
21169
|
.find((token) => {
|
|
21087
21170
|
const { xc, sheetName: sheet } = splitReference(token.value);
|
|
21088
21171
|
const sheetName = sheet || this.getters.getSheetName(this.sheetId);
|
|
21089
|
-
if (this.getters.getSheetName(activeSheetId)
|
|
21172
|
+
if (!isSheetNameEqual(this.getters.getSheetName(activeSheetId), sheetName)) {
|
|
21090
21173
|
return false;
|
|
21091
21174
|
}
|
|
21092
21175
|
const refRange = this.getters.getRangeFromSheetXC(activeSheetId, xc);
|
|
@@ -22965,6 +23048,7 @@ const CHART_COMMON_OPTIONS = {
|
|
|
22965
23048
|
},
|
|
22966
23049
|
},
|
|
22967
23050
|
animation: false,
|
|
23051
|
+
events: ["mousemove", "mouseout", "click", "touchstart", "touchmove", "mouseup"],
|
|
22968
23052
|
};
|
|
22969
23053
|
function chartToImage(runtime, figure, type) {
|
|
22970
23054
|
// wrap the canvas in a div with a fixed size because chart.js would
|
|
@@ -22981,8 +23065,7 @@ function chartToImage(runtime, figure, type) {
|
|
|
22981
23065
|
if ("chartJsConfig" in runtime) {
|
|
22982
23066
|
const config = deepCopy(runtime.chartJsConfig);
|
|
22983
23067
|
config.plugins = [backgroundColorChartJSPlugin];
|
|
22984
|
-
const
|
|
22985
|
-
const chart = new Chart(canvas, config);
|
|
23068
|
+
const chart = new window.Chart(canvas, config);
|
|
22986
23069
|
const imgContent = chart.toBase64Image();
|
|
22987
23070
|
chart.destroy();
|
|
22988
23071
|
div.remove();
|
|
@@ -24548,7 +24631,7 @@ function getRangeSize(reference, defaultSheetIndex, data) {
|
|
|
24548
24631
|
({ xc, sheetName } = splitReference(reference));
|
|
24549
24632
|
let rangeSheetIndex;
|
|
24550
24633
|
if (sheetName) {
|
|
24551
|
-
const index = data.sheets.findIndex((sheet) => sheet.name
|
|
24634
|
+
const index = data.sheets.findIndex((sheet) => isSheetNameEqual(sheet.name, sheetName));
|
|
24552
24635
|
if (index < 0) {
|
|
24553
24636
|
throw new Error("Unable to find a sheet with the name " + sheetName);
|
|
24554
24637
|
}
|
|
@@ -24889,7 +24972,7 @@ function convertFormula(formula, data) {
|
|
|
24889
24972
|
formula = formula.replace(externalReferenceRegex, (match, externalRefId, sheetName, cellRef) => {
|
|
24890
24973
|
externalRefId = Number(externalRefId) - 1;
|
|
24891
24974
|
cellRef = cellRef.replace(/\$/g, "");
|
|
24892
|
-
const sheetIndex = data.externalBooks[externalRefId].sheetNames.findIndex((name) => name
|
|
24975
|
+
const sheetIndex = data.externalBooks[externalRefId].sheetNames.findIndex((name) => isSheetNameEqual(name, sheetName));
|
|
24893
24976
|
if (sheetIndex === -1) {
|
|
24894
24977
|
return match;
|
|
24895
24978
|
}
|
|
@@ -25540,7 +25623,7 @@ function convertPivotTableConfig(pivotTable) {
|
|
|
25540
25623
|
*/
|
|
25541
25624
|
function convertTableFormulaReferences(convertedSheets, xlsxSheets) {
|
|
25542
25625
|
for (let tableSheet of convertedSheets) {
|
|
25543
|
-
const tables = xlsxSheets.find((s) => s.sheetName
|
|
25626
|
+
const tables = xlsxSheets.find((s) => isSheetNameEqual(s.sheetName, tableSheet.name)).tables;
|
|
25544
25627
|
for (let table of tables) {
|
|
25545
25628
|
const tabRef = table.name + "[";
|
|
25546
25629
|
for (let sheet of convertedSheets) {
|
|
@@ -27975,6 +28058,7 @@ function repairInitialMessages(data, initialMessages) {
|
|
|
27975
28058
|
initialMessages = dropCommands(initialMessages, "SORT_CELLS");
|
|
27976
28059
|
initialMessages = dropCommands(initialMessages, "SET_DECIMAL");
|
|
27977
28060
|
initialMessages = fixChartDefinitions(data, initialMessages);
|
|
28061
|
+
initialMessages = fixTranslatedDuplicateSheetName(data, initialMessages);
|
|
27978
28062
|
return initialMessages;
|
|
27979
28063
|
}
|
|
27980
28064
|
/**
|
|
@@ -28074,6 +28158,40 @@ function fixChartDefinitions(data, initialMessages) {
|
|
|
28074
28158
|
}
|
|
28075
28159
|
return messages;
|
|
28076
28160
|
}
|
|
28161
|
+
function fixTranslatedDuplicateSheetName(data, initialMessages) {
|
|
28162
|
+
const sheetNames = {};
|
|
28163
|
+
for (const sheet of data.sheets || []) {
|
|
28164
|
+
sheetNames[sheet.id] = sheet.name;
|
|
28165
|
+
}
|
|
28166
|
+
const messages = [];
|
|
28167
|
+
for (const message of initialMessages) {
|
|
28168
|
+
if (message.type === "REMOTE_REVISION") {
|
|
28169
|
+
const commands = [];
|
|
28170
|
+
for (const cmd of message.commands) {
|
|
28171
|
+
switch (cmd.type) {
|
|
28172
|
+
case "DUPLICATE_SHEET":
|
|
28173
|
+
cmd.sheetNameTo =
|
|
28174
|
+
cmd.sheetNameTo ??
|
|
28175
|
+
getDuplicateSheetName(sheetNames[cmd.sheetId], Object.values(sheetNames));
|
|
28176
|
+
break;
|
|
28177
|
+
case "CREATE_SHEET":
|
|
28178
|
+
case "RENAME_SHEET":
|
|
28179
|
+
sheetNames[cmd.sheetId] = cmd.name || getNextSheetName(Object.values(sheetNames));
|
|
28180
|
+
break;
|
|
28181
|
+
}
|
|
28182
|
+
commands.push(cmd);
|
|
28183
|
+
}
|
|
28184
|
+
messages.push({
|
|
28185
|
+
...message,
|
|
28186
|
+
commands,
|
|
28187
|
+
});
|
|
28188
|
+
}
|
|
28189
|
+
else {
|
|
28190
|
+
messages.push(message);
|
|
28191
|
+
}
|
|
28192
|
+
}
|
|
28193
|
+
return initialMessages;
|
|
28194
|
+
}
|
|
28077
28195
|
// -----------------------------------------------------------------------------
|
|
28078
28196
|
// Helpers
|
|
28079
28197
|
// -----------------------------------------------------------------------------
|
|
@@ -28870,12 +28988,11 @@ function canBeLinearChart(definition, dataSets, labelRange, getters) {
|
|
|
28870
28988
|
}
|
|
28871
28989
|
let missingTimeAdapterAlreadyWarned = false;
|
|
28872
28990
|
function isLuxonTimeAdapterInstalled() {
|
|
28873
|
-
|
|
28874
|
-
if (!Chart) {
|
|
28991
|
+
if (!window.Chart) {
|
|
28875
28992
|
return false;
|
|
28876
28993
|
}
|
|
28877
28994
|
// @ts-ignore
|
|
28878
|
-
const adapter = new Chart._adapters._date({});
|
|
28995
|
+
const adapter = new window.Chart._adapters._date({});
|
|
28879
28996
|
const isInstalled = adapter._id === "luxon";
|
|
28880
28997
|
if (!isInstalled && !missingTimeAdapterAlreadyWarned) {
|
|
28881
28998
|
missingTimeAdapterAlreadyWarned = true;
|
|
@@ -29513,6 +29630,9 @@ const INTERACTIVE_LEGEND_CONFIG = {
|
|
|
29513
29630
|
target.style.cursor = "default";
|
|
29514
29631
|
},
|
|
29515
29632
|
onClick: (event, legendItem, legend) => {
|
|
29633
|
+
if (event.type !== "click") {
|
|
29634
|
+
return;
|
|
29635
|
+
}
|
|
29516
29636
|
const index = legendItem.datasetIndex;
|
|
29517
29637
|
if (!legend.legendItems || index === undefined) {
|
|
29518
29638
|
return;
|
|
@@ -32495,12 +32615,20 @@ class HoveredCellStore extends SpreadsheetStore {
|
|
|
32495
32615
|
}
|
|
32496
32616
|
}
|
|
32497
32617
|
hover(position) {
|
|
32618
|
+
if (position.col === this.col && position.row === this.row) {
|
|
32619
|
+
return "noStateChange";
|
|
32620
|
+
}
|
|
32498
32621
|
this.col = position.col;
|
|
32499
32622
|
this.row = position.row;
|
|
32623
|
+
return;
|
|
32500
32624
|
}
|
|
32501
32625
|
clear() {
|
|
32626
|
+
if (this.col === undefined && this.row === undefined) {
|
|
32627
|
+
return "noStateChange";
|
|
32628
|
+
}
|
|
32502
32629
|
this.col = undefined;
|
|
32503
32630
|
this.row = undefined;
|
|
32631
|
+
return;
|
|
32504
32632
|
}
|
|
32505
32633
|
}
|
|
32506
32634
|
|
|
@@ -32522,7 +32650,11 @@ class CellPopoverStore extends SpreadsheetStore {
|
|
|
32522
32650
|
this.persistentPopover = { col, row, sheetId, type };
|
|
32523
32651
|
}
|
|
32524
32652
|
close() {
|
|
32653
|
+
if (!this.persistentPopover) {
|
|
32654
|
+
return "noStateChange";
|
|
32655
|
+
}
|
|
32525
32656
|
this.persistentPopover = undefined;
|
|
32657
|
+
return;
|
|
32526
32658
|
}
|
|
32527
32659
|
get persistentCellPopover() {
|
|
32528
32660
|
return ((this.persistentPopover && { isOpen: true, ...this.persistentPopover }) || { isOpen: false });
|
|
@@ -33412,10 +33544,13 @@ const duplicateSheet = {
|
|
|
33412
33544
|
name: _t("Duplicate"),
|
|
33413
33545
|
execute: (env) => {
|
|
33414
33546
|
const sheetIdFrom = env.model.getters.getActiveSheetId();
|
|
33547
|
+
const sheetNameFrom = env.model.getters.getSheetName(sheetIdFrom);
|
|
33415
33548
|
const sheetIdTo = env.model.uuidGenerator.smallUuid();
|
|
33549
|
+
const sheetNameTo = env.model.getters.getDuplicateSheetName(sheetNameFrom);
|
|
33416
33550
|
env.model.dispatch("DUPLICATE_SHEET", {
|
|
33417
33551
|
sheetId: sheetIdFrom,
|
|
33418
33552
|
sheetIdTo,
|
|
33553
|
+
sheetNameTo,
|
|
33419
33554
|
});
|
|
33420
33555
|
env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom, sheetIdTo });
|
|
33421
33556
|
},
|
|
@@ -38618,7 +38753,7 @@ class GenericChartConfigPanel extends owl.Component {
|
|
|
38618
38753
|
const cancelledReasons = [
|
|
38619
38754
|
...(this.state.datasetDispatchResult?.reasons || []),
|
|
38620
38755
|
...(this.state.labelsDispatchResult?.reasons || []),
|
|
38621
|
-
];
|
|
38756
|
+
].filter((reason) => reason !== "NoChanges" /* CommandResult.NoChanges */);
|
|
38622
38757
|
return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
|
|
38623
38758
|
}
|
|
38624
38759
|
get isDatasetInvalid() {
|
|
@@ -39975,10 +40110,18 @@ class GaugeChartConfigPanel extends owl.Component {
|
|
|
39975
40110
|
}
|
|
39976
40111
|
|
|
39977
40112
|
class DOMFocusableElementStore {
|
|
39978
|
-
mutators = ["setFocusableElement"];
|
|
40113
|
+
mutators = ["setFocusableElement", "focus"];
|
|
39979
40114
|
focusableElement = undefined;
|
|
39980
40115
|
setFocusableElement(element) {
|
|
39981
40116
|
this.focusableElement = element;
|
|
40117
|
+
return "noStateChange";
|
|
40118
|
+
}
|
|
40119
|
+
focus() {
|
|
40120
|
+
if (this.focusableElement === document.activeElement) {
|
|
40121
|
+
return "noStateChange";
|
|
40122
|
+
}
|
|
40123
|
+
this.focusableElement?.focus();
|
|
40124
|
+
return;
|
|
39982
40125
|
}
|
|
39983
40126
|
}
|
|
39984
40127
|
|
|
@@ -40566,7 +40709,7 @@ class Composer extends owl.Component {
|
|
|
40566
40709
|
if (document.activeElement === this.contentHelper.el &&
|
|
40567
40710
|
this.props.composerStore.editionMode === "inactive" &&
|
|
40568
40711
|
!this.props.isDefaultFocus) {
|
|
40569
|
-
this.DOMFocusableElementStore.
|
|
40712
|
+
this.DOMFocusableElementStore.focus();
|
|
40570
40713
|
}
|
|
40571
40714
|
});
|
|
40572
40715
|
owl.useEffect(() => {
|
|
@@ -40840,6 +40983,13 @@ class Composer extends owl.Component {
|
|
|
40840
40983
|
openAssistant() {
|
|
40841
40984
|
this.assistant.forcedClosed = false;
|
|
40842
40985
|
}
|
|
40986
|
+
onWheel(event) {
|
|
40987
|
+
// detect if scrollbar is available
|
|
40988
|
+
if (this.composerRef.el &&
|
|
40989
|
+
this.composerRef.el.scrollHeight > this.composerRef.el.clientHeight) {
|
|
40990
|
+
event.stopPropagation();
|
|
40991
|
+
}
|
|
40992
|
+
}
|
|
40843
40993
|
// ---------------------------------------------------------------------------
|
|
40844
40994
|
// Private
|
|
40845
40995
|
// ---------------------------------------------------------------------------
|
|
@@ -46316,8 +46466,8 @@ function compareDimensionValues(dimension, a, b) {
|
|
|
46316
46466
|
|
|
46317
46467
|
const NULL_SYMBOL = Symbol("NULL");
|
|
46318
46468
|
function createDate(dimension, value, locale) {
|
|
46319
|
-
const granularity = dimension.granularity;
|
|
46320
|
-
if (!
|
|
46469
|
+
const granularity = dimension.granularity || "month";
|
|
46470
|
+
if (!(granularity in MAP_VALUE_DIMENSION_DATE)) {
|
|
46321
46471
|
throw new Error(`Unknown date granularity: ${granularity}`);
|
|
46322
46472
|
}
|
|
46323
46473
|
const keyInMap = typeof value === "number" || typeof value === "string" ? value : NULL_SYMBOL;
|
|
@@ -46336,6 +46486,9 @@ function createDate(dimension, value, locale) {
|
|
|
46336
46486
|
case "month_number":
|
|
46337
46487
|
number = date.getMonth() + 1;
|
|
46338
46488
|
break;
|
|
46489
|
+
case "month":
|
|
46490
|
+
number = Math.floor(toNumber(value, locale));
|
|
46491
|
+
break;
|
|
46339
46492
|
case "iso_week_number":
|
|
46340
46493
|
number = date.getIsoWeek();
|
|
46341
46494
|
break;
|
|
@@ -46429,6 +46582,10 @@ const MAP_VALUE_DIMENSION_DATE = {
|
|
|
46429
46582
|
set: new Set(),
|
|
46430
46583
|
values: {},
|
|
46431
46584
|
},
|
|
46585
|
+
month: {
|
|
46586
|
+
set: new Set(),
|
|
46587
|
+
values: {},
|
|
46588
|
+
},
|
|
46432
46589
|
iso_week_number: {
|
|
46433
46590
|
set: new Set(),
|
|
46434
46591
|
values: {},
|
|
@@ -46639,7 +46796,7 @@ class SpreadsheetPivot {
|
|
|
46639
46796
|
const cells = this.filterDataEntriesFromDomain(this.dataEntries, domain);
|
|
46640
46797
|
const finalCell = cells[0]?.[dimension.nameWithGranularity];
|
|
46641
46798
|
if (dimension.type === "datetime") {
|
|
46642
|
-
const adapter = pivotTimeAdapter(dimension.granularity);
|
|
46799
|
+
const adapter = pivotTimeAdapter((dimension.granularity || "month"));
|
|
46643
46800
|
return adapter.toValueAndFormat(lastNode.value, this.getters.getLocale());
|
|
46644
46801
|
}
|
|
46645
46802
|
if (!finalCell) {
|
|
@@ -46757,7 +46914,7 @@ class SpreadsheetPivot {
|
|
|
46757
46914
|
if (nonEmptyCells.length === 0) {
|
|
46758
46915
|
return "integer";
|
|
46759
46916
|
}
|
|
46760
|
-
if (nonEmptyCells.every((cell) => cell.format && isDateTimeFormat(cell.format))) {
|
|
46917
|
+
if (nonEmptyCells.every((cell) => cell.type === CellValueType.number && cell.format && isDateTimeFormat(cell.format))) {
|
|
46761
46918
|
return "datetime";
|
|
46762
46919
|
}
|
|
46763
46920
|
if (nonEmptyCells.every((cell) => cell.type === CellValueType.boolean)) {
|
|
@@ -46836,7 +46993,12 @@ class SpreadsheetPivot {
|
|
|
46836
46993
|
entry[field.name] = { value: null, type: CellValueType.empty, formattedValue: "" };
|
|
46837
46994
|
}
|
|
46838
46995
|
else {
|
|
46839
|
-
|
|
46996
|
+
if (field.type === "char") {
|
|
46997
|
+
entry[field.name] = { ...cell, value: cell.formattedValue || null };
|
|
46998
|
+
}
|
|
46999
|
+
else {
|
|
47000
|
+
entry[field.name] = cell;
|
|
47001
|
+
}
|
|
46840
47002
|
}
|
|
46841
47003
|
}
|
|
46842
47004
|
entry["__count"] = { value: 1, type: CellValueType.number, formattedValue: "1" };
|
|
@@ -46850,7 +47012,7 @@ class SpreadsheetPivot {
|
|
|
46850
47012
|
for (const entry of dataEntries) {
|
|
46851
47013
|
for (const dimension of dateDimensions) {
|
|
46852
47014
|
const value = createDate(dimension, entry[dimension.fieldName]?.value || null, this.getters.getLocale());
|
|
46853
|
-
const adapter = pivotTimeAdapter(dimension.granularity);
|
|
47015
|
+
const adapter = pivotTimeAdapter((dimension.granularity || "month"));
|
|
46854
47016
|
const { format, value: valueToFormat } = adapter.toValueAndFormat(value, locale);
|
|
46855
47017
|
entry[dimension.nameWithGranularity] = {
|
|
46856
47018
|
value,
|
|
@@ -46870,6 +47032,7 @@ const dateGranularities = [
|
|
|
46870
47032
|
"year",
|
|
46871
47033
|
"quarter_number",
|
|
46872
47034
|
"month_number",
|
|
47035
|
+
"month",
|
|
46873
47036
|
"iso_week_number",
|
|
46874
47037
|
"day_of_month",
|
|
46875
47038
|
"day",
|
|
@@ -47120,7 +47283,7 @@ class PivotSidePanelStore extends SpreadsheetStore {
|
|
|
47120
47283
|
: this.datetimeGranularities);
|
|
47121
47284
|
}
|
|
47122
47285
|
for (const field of dateFields) {
|
|
47123
|
-
granularitiesPerFields[field.fieldName].delete(field.granularity);
|
|
47286
|
+
granularitiesPerFields[field.fieldName].delete(field.granularity || "month");
|
|
47124
47287
|
}
|
|
47125
47288
|
return granularitiesPerFields;
|
|
47126
47289
|
}
|
|
@@ -49290,6 +49453,8 @@ class GridComposer extends owl.Component {
|
|
|
49290
49453
|
}
|
|
49291
49454
|
get composerProps() {
|
|
49292
49455
|
const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
|
|
49456
|
+
// Remove the wrapper border width
|
|
49457
|
+
const maxHeight = this.props.gridDims.height - this.rect.y - 2 * COMPOSER_BORDER_WIDTH;
|
|
49293
49458
|
return {
|
|
49294
49459
|
rect: { ...this.rect },
|
|
49295
49460
|
delimitation: {
|
|
@@ -49307,6 +49472,7 @@ class GridComposer extends owl.Component {
|
|
|
49307
49472
|
}),
|
|
49308
49473
|
onInputContextMenu: this.props.onInputContextMenu,
|
|
49309
49474
|
composerStore: this.composerStore,
|
|
49475
|
+
inputStyle: `max-height: ${maxHeight}px;`,
|
|
49310
49476
|
};
|
|
49311
49477
|
}
|
|
49312
49478
|
get containerStyle() {
|
|
@@ -51970,10 +52136,6 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
51970
52136
|
ctx.scale(dpr, dpr);
|
|
51971
52137
|
for (const layer of OrderedLayers()) {
|
|
51972
52138
|
model.drawLayer(renderingContext, layer);
|
|
51973
|
-
// @ts-ignore 'drawLayer' is not declated as a mutator because:
|
|
51974
|
-
// it does not mutate anything. Most importantly it's used
|
|
51975
|
-
// during rendering. Invoking a mutator during rendering would
|
|
51976
|
-
// trigger another rendering, ultimately resulting in an infinite loop.
|
|
51977
52139
|
rendererStore.drawLayer(renderingContext, layer);
|
|
51978
52140
|
}
|
|
51979
52141
|
}
|
|
@@ -52664,7 +52826,7 @@ class Grid extends owl.Component {
|
|
|
52664
52826
|
this.cellPopovers = useStore(CellPopoverStore);
|
|
52665
52827
|
owl.useEffect(() => {
|
|
52666
52828
|
if (!this.sidePanel.isOpen) {
|
|
52667
|
-
this.DOMFocusableElementStore.
|
|
52829
|
+
this.DOMFocusableElementStore.focus();
|
|
52668
52830
|
}
|
|
52669
52831
|
}, () => [this.sidePanel.isOpen]);
|
|
52670
52832
|
useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
|
|
@@ -52874,7 +53036,7 @@ class Grid extends owl.Component {
|
|
|
52874
53036
|
focusDefaultElement() {
|
|
52875
53037
|
if (!this.env.model.getters.getSelectedFigureId() &&
|
|
52876
53038
|
this.composerFocusStore.activeComposer.editionMode === "inactive") {
|
|
52877
|
-
this.DOMFocusableElementStore.
|
|
53039
|
+
this.DOMFocusableElementStore.focus();
|
|
52878
53040
|
}
|
|
52879
53041
|
}
|
|
52880
53042
|
get gridEl() {
|
|
@@ -53219,6 +53381,322 @@ class Grid extends owl.Component {
|
|
|
53219
53381
|
}
|
|
53220
53382
|
}
|
|
53221
53383
|
|
|
53384
|
+
css /* scss */ `
|
|
53385
|
+
.o_pivot_html_renderer {
|
|
53386
|
+
width: 100%;
|
|
53387
|
+
border-collapse: collapse;
|
|
53388
|
+
|
|
53389
|
+
&:hover {
|
|
53390
|
+
cursor: pointer;
|
|
53391
|
+
}
|
|
53392
|
+
|
|
53393
|
+
td,
|
|
53394
|
+
th {
|
|
53395
|
+
border: 1px solid #dee2e6;
|
|
53396
|
+
background-color: #fff;
|
|
53397
|
+
padding: 0.3rem;
|
|
53398
|
+
white-space: nowrap;
|
|
53399
|
+
|
|
53400
|
+
&:hover {
|
|
53401
|
+
filter: brightness(0.9);
|
|
53402
|
+
}
|
|
53403
|
+
}
|
|
53404
|
+
|
|
53405
|
+
td {
|
|
53406
|
+
text-align: right;
|
|
53407
|
+
}
|
|
53408
|
+
|
|
53409
|
+
th {
|
|
53410
|
+
background-color: #f5f5f5;
|
|
53411
|
+
font-weight: bold;
|
|
53412
|
+
color: black;
|
|
53413
|
+
}
|
|
53414
|
+
|
|
53415
|
+
.o_missing_value {
|
|
53416
|
+
color: #46646d;
|
|
53417
|
+
background: #e7f2f6;
|
|
53418
|
+
}
|
|
53419
|
+
}
|
|
53420
|
+
`;
|
|
53421
|
+
class PivotHTMLRenderer extends owl.Component {
|
|
53422
|
+
static template = "o_spreadsheet.PivotHTMLRenderer";
|
|
53423
|
+
static components = { Checkbox };
|
|
53424
|
+
static props = {
|
|
53425
|
+
pivotId: String,
|
|
53426
|
+
onCellClicked: Function,
|
|
53427
|
+
};
|
|
53428
|
+
pivot = this.env.model.getters.getPivot(this.props.pivotId);
|
|
53429
|
+
data = {
|
|
53430
|
+
columns: [],
|
|
53431
|
+
rows: [],
|
|
53432
|
+
values: [],
|
|
53433
|
+
};
|
|
53434
|
+
state = owl.useState({
|
|
53435
|
+
showMissingValuesOnly: false,
|
|
53436
|
+
});
|
|
53437
|
+
setup() {
|
|
53438
|
+
const table = this.pivot.getTableStructure();
|
|
53439
|
+
const formulaId = this.env.model.getters.getPivotFormulaId(this.props.pivotId);
|
|
53440
|
+
this.data = {
|
|
53441
|
+
columns: this._buildColHeaders(formulaId, table),
|
|
53442
|
+
rows: this._buildRowHeaders(formulaId, table),
|
|
53443
|
+
values: this._buildValues(formulaId, table),
|
|
53444
|
+
};
|
|
53445
|
+
}
|
|
53446
|
+
get tracker() {
|
|
53447
|
+
return this.env.model.getters.getPivotPresenceTracker(this.props.pivotId);
|
|
53448
|
+
}
|
|
53449
|
+
// ---------------------------------------------------------------------
|
|
53450
|
+
// Missing values building
|
|
53451
|
+
// ---------------------------------------------------------------------
|
|
53452
|
+
/**
|
|
53453
|
+
* Retrieve the data to display in the Pivot Table
|
|
53454
|
+
* In the case when showMissingValuesOnly is false, the returned value
|
|
53455
|
+
* is the complete data
|
|
53456
|
+
* In the case when showMissingValuesOnly is true, the returned value is
|
|
53457
|
+
* the data which contains only missing values in the rows and cols. In
|
|
53458
|
+
* the rows, we also return the parent rows of rows which contains missing
|
|
53459
|
+
* values, to give context to the user.
|
|
53460
|
+
*
|
|
53461
|
+
*/
|
|
53462
|
+
getTableData() {
|
|
53463
|
+
if (!this.state.showMissingValuesOnly) {
|
|
53464
|
+
return this.data;
|
|
53465
|
+
}
|
|
53466
|
+
const colIndexes = this.getColumnsIndexes();
|
|
53467
|
+
const rowIndexes = this.getRowsIndexes();
|
|
53468
|
+
const columns = this.buildColumnsMissing(colIndexes);
|
|
53469
|
+
const rows = this.buildRowsMissing(rowIndexes);
|
|
53470
|
+
const values = this.buildValuesMissing(colIndexes, rowIndexes);
|
|
53471
|
+
return { columns, rows, values };
|
|
53472
|
+
}
|
|
53473
|
+
/**
|
|
53474
|
+
* Retrieve the parents of the given row
|
|
53475
|
+
* ex:
|
|
53476
|
+
* Australia
|
|
53477
|
+
* January
|
|
53478
|
+
* February
|
|
53479
|
+
* The parent of "January" is "Australia"
|
|
53480
|
+
*/
|
|
53481
|
+
addRecursiveRow(index) {
|
|
53482
|
+
const rows = this.pivot.getTableStructure().rows;
|
|
53483
|
+
const row = [...rows[index].values];
|
|
53484
|
+
if (row.length <= 1) {
|
|
53485
|
+
return [index];
|
|
53486
|
+
}
|
|
53487
|
+
row.pop();
|
|
53488
|
+
const parentRowIndex = rows.findIndex((r) => JSON.stringify(r.values) === JSON.stringify(row));
|
|
53489
|
+
return [index].concat(this.addRecursiveRow(parentRowIndex));
|
|
53490
|
+
}
|
|
53491
|
+
/**
|
|
53492
|
+
* Create the columns to be used, based on the indexes of the columns in
|
|
53493
|
+
* which a missing value is present
|
|
53494
|
+
*
|
|
53495
|
+
*/
|
|
53496
|
+
buildColumnsMissing(indexes) {
|
|
53497
|
+
// columnsMap explode the columns in an array of array of the same
|
|
53498
|
+
// size with the index of each column, repeated 'span' times.
|
|
53499
|
+
// ex:
|
|
53500
|
+
// | A | B |
|
|
53501
|
+
// | 1 | 2 | 3 |
|
|
53502
|
+
// => [
|
|
53503
|
+
// [0, 0, 1]
|
|
53504
|
+
// [0, 1, 2]
|
|
53505
|
+
// ]
|
|
53506
|
+
const columnsMap = [];
|
|
53507
|
+
for (const column of this.data.columns) {
|
|
53508
|
+
const columnMap = [];
|
|
53509
|
+
for (const index in column) {
|
|
53510
|
+
for (let i = 0; i < column[index].span; i++) {
|
|
53511
|
+
columnMap.push(parseInt(index, 10));
|
|
53512
|
+
}
|
|
53513
|
+
}
|
|
53514
|
+
columnsMap.push(columnMap);
|
|
53515
|
+
}
|
|
53516
|
+
// Remove the columns that are not present in indexes
|
|
53517
|
+
for (let i = columnsMap[columnsMap.length - 1].length; i >= 0; i--) {
|
|
53518
|
+
if (!indexes.includes(i)) {
|
|
53519
|
+
for (const columnMap of columnsMap) {
|
|
53520
|
+
columnMap.splice(i, 1);
|
|
53521
|
+
}
|
|
53522
|
+
}
|
|
53523
|
+
}
|
|
53524
|
+
// Build the columns
|
|
53525
|
+
const columns = [];
|
|
53526
|
+
for (const mapIndex in columnsMap) {
|
|
53527
|
+
const column = [];
|
|
53528
|
+
let index = undefined;
|
|
53529
|
+
let span = 1;
|
|
53530
|
+
for (let i = 0; i < columnsMap[mapIndex].length; i++) {
|
|
53531
|
+
if (index !== columnsMap[mapIndex][i]) {
|
|
53532
|
+
if (index !== undefined) {
|
|
53533
|
+
column.push(Object.assign({}, this.data.columns[mapIndex][index], { span }));
|
|
53534
|
+
}
|
|
53535
|
+
index = columnsMap[mapIndex][i];
|
|
53536
|
+
span = 1;
|
|
53537
|
+
}
|
|
53538
|
+
else {
|
|
53539
|
+
span++;
|
|
53540
|
+
}
|
|
53541
|
+
}
|
|
53542
|
+
if (index !== undefined) {
|
|
53543
|
+
column.push(Object.assign({}, this.data.columns[mapIndex][index], { span }));
|
|
53544
|
+
}
|
|
53545
|
+
columns.push(column);
|
|
53546
|
+
}
|
|
53547
|
+
return columns;
|
|
53548
|
+
}
|
|
53549
|
+
/**
|
|
53550
|
+
* Create the rows to be used, based on the indexes of the rows in
|
|
53551
|
+
* which a missing value is present.
|
|
53552
|
+
*/
|
|
53553
|
+
buildRowsMissing(indexes) {
|
|
53554
|
+
return indexes.map((index) => this.data.rows[index]);
|
|
53555
|
+
}
|
|
53556
|
+
/**
|
|
53557
|
+
* Create the value to be used, based on the indexes of the columns and
|
|
53558
|
+
* rows in which a missing value is present.
|
|
53559
|
+
*/
|
|
53560
|
+
buildValuesMissing(colIndexes, rowIndexes) {
|
|
53561
|
+
const values = colIndexes.map(() => []);
|
|
53562
|
+
for (const row of rowIndexes) {
|
|
53563
|
+
for (const col in colIndexes) {
|
|
53564
|
+
values[col].push(this.data.values[colIndexes[col]][row]);
|
|
53565
|
+
}
|
|
53566
|
+
}
|
|
53567
|
+
return values;
|
|
53568
|
+
}
|
|
53569
|
+
getColumnsIndexes() {
|
|
53570
|
+
const indexes = new Set();
|
|
53571
|
+
for (let i = 0; i < this.data.columns.length; i++) {
|
|
53572
|
+
const exploded = [];
|
|
53573
|
+
for (let y = 0; y < this.data.columns[i].length; y++) {
|
|
53574
|
+
for (let x = 0; x < this.data.columns[i][y].span; x++) {
|
|
53575
|
+
exploded.push(this.data.columns[i][y]);
|
|
53576
|
+
}
|
|
53577
|
+
}
|
|
53578
|
+
for (let y = 0; y < exploded.length; y++) {
|
|
53579
|
+
if (exploded[y].isMissing) {
|
|
53580
|
+
indexes.add(y);
|
|
53581
|
+
}
|
|
53582
|
+
}
|
|
53583
|
+
}
|
|
53584
|
+
for (let i = 0; i < this.data.columns[this.data.columns.length - 1].length; i++) {
|
|
53585
|
+
const values = this.data.values[i];
|
|
53586
|
+
if (values.find((x) => x.isMissing)) {
|
|
53587
|
+
indexes.add(i);
|
|
53588
|
+
}
|
|
53589
|
+
}
|
|
53590
|
+
return Array.from(indexes).sort((a, b) => a - b);
|
|
53591
|
+
}
|
|
53592
|
+
getRowsIndexes() {
|
|
53593
|
+
const rowIndexes = new Set();
|
|
53594
|
+
for (let i = 0; i < this.data.rows.length; i++) {
|
|
53595
|
+
if (this.data.rows[i].isMissing) {
|
|
53596
|
+
rowIndexes.add(i);
|
|
53597
|
+
}
|
|
53598
|
+
for (const col of this.data.values) {
|
|
53599
|
+
if (col[i].isMissing) {
|
|
53600
|
+
this.addRecursiveRow(i).forEach((x) => rowIndexes.add(x));
|
|
53601
|
+
}
|
|
53602
|
+
}
|
|
53603
|
+
}
|
|
53604
|
+
return Array.from(rowIndexes).sort((a, b) => a - b);
|
|
53605
|
+
}
|
|
53606
|
+
// ---------------------------------------------------------------------
|
|
53607
|
+
// Data table creation
|
|
53608
|
+
// ---------------------------------------------------------------------
|
|
53609
|
+
_buildColHeaders(id, table) {
|
|
53610
|
+
const headers = [];
|
|
53611
|
+
for (const row of table.columns) {
|
|
53612
|
+
const current = [];
|
|
53613
|
+
for (const cell of row) {
|
|
53614
|
+
const args = [];
|
|
53615
|
+
for (let i = 0; i < cell.fields.length; i++) {
|
|
53616
|
+
args.push({ value: cell.fields[i] }, { value: cell.values[i] });
|
|
53617
|
+
}
|
|
53618
|
+
const domain = this.pivot.parseArgsToPivotDomain(args);
|
|
53619
|
+
const locale = this.env.model.getters.getLocale();
|
|
53620
|
+
if (domain.at(-1)?.field === "measure") {
|
|
53621
|
+
const { value, format } = this.pivot.getPivotMeasureValue(toString(domain.at(-1).value), domain);
|
|
53622
|
+
current.push({
|
|
53623
|
+
formula: `=PIVOT.HEADER(${generatePivotArgs(id, domain).join(",")})`,
|
|
53624
|
+
value: formatValue(value, { format, locale }),
|
|
53625
|
+
span: cell.width,
|
|
53626
|
+
isMissing: !this.tracker?.isHeaderPresent(domain),
|
|
53627
|
+
});
|
|
53628
|
+
}
|
|
53629
|
+
else {
|
|
53630
|
+
const { value, format } = this.pivot.getPivotHeaderValueAndFormat(domain);
|
|
53631
|
+
current.push({
|
|
53632
|
+
formula: `=PIVOT.HEADER(${generatePivotArgs(id, domain).join(",")})`,
|
|
53633
|
+
value: formatValue(value, { format, locale }),
|
|
53634
|
+
span: cell.width,
|
|
53635
|
+
isMissing: !this.tracker?.isHeaderPresent(domain),
|
|
53636
|
+
});
|
|
53637
|
+
}
|
|
53638
|
+
}
|
|
53639
|
+
headers.push(current);
|
|
53640
|
+
}
|
|
53641
|
+
const last = headers[headers.length - 1];
|
|
53642
|
+
headers[headers.length - 1] = last.map((cell) => {
|
|
53643
|
+
if (!cell.isMissing) {
|
|
53644
|
+
cell.style = "color: #756f6f;";
|
|
53645
|
+
}
|
|
53646
|
+
return cell;
|
|
53647
|
+
});
|
|
53648
|
+
return headers;
|
|
53649
|
+
}
|
|
53650
|
+
_buildRowHeaders(id, table) {
|
|
53651
|
+
const headers = [];
|
|
53652
|
+
for (const row of table.rows) {
|
|
53653
|
+
const args = [];
|
|
53654
|
+
for (let i = 0; i < row.fields.length; i++) {
|
|
53655
|
+
args.push({ value: row.fields[i] }, { value: row.values[i] });
|
|
53656
|
+
}
|
|
53657
|
+
const domain = this.pivot.parseArgsToPivotDomain(args);
|
|
53658
|
+
const { value, format } = this.pivot.getPivotHeaderValueAndFormat(domain);
|
|
53659
|
+
const locale = this.env.model.getters.getLocale();
|
|
53660
|
+
const cell = {
|
|
53661
|
+
formula: `=PIVOT.HEADER(${generatePivotArgs(id, domain).join(",")})`,
|
|
53662
|
+
value: formatValue(value, { format, locale }),
|
|
53663
|
+
isMissing: !this.tracker?.isHeaderPresent(domain),
|
|
53664
|
+
};
|
|
53665
|
+
if (row.indent > 1) {
|
|
53666
|
+
cell.style = `padding-left: ${row.indent - 1 * 10}px`;
|
|
53667
|
+
}
|
|
53668
|
+
headers.push(cell);
|
|
53669
|
+
}
|
|
53670
|
+
return headers;
|
|
53671
|
+
}
|
|
53672
|
+
_buildValues(id, table) {
|
|
53673
|
+
const values = [];
|
|
53674
|
+
for (const col of table.columns.at(-1) || []) {
|
|
53675
|
+
const current = [];
|
|
53676
|
+
const measure = toString(col.values[col.values.length - 1]);
|
|
53677
|
+
for (const row of table.rows) {
|
|
53678
|
+
const args = [];
|
|
53679
|
+
for (let i = 0; i < row.fields.length; i++) {
|
|
53680
|
+
args.push({ value: row.fields[i] }, { value: row.values[i] });
|
|
53681
|
+
}
|
|
53682
|
+
for (let i = 0; i < col.fields.length - 1; i++) {
|
|
53683
|
+
args.push({ value: col.fields[i] }, { value: col.values[i] });
|
|
53684
|
+
}
|
|
53685
|
+
const domain = this.pivot.parseArgsToPivotDomain(args);
|
|
53686
|
+
const { value, format } = this.pivot.getPivotCellValueAndFormat(measure, domain);
|
|
53687
|
+
const locale = this.env.model.getters.getLocale();
|
|
53688
|
+
current.push({
|
|
53689
|
+
formula: `=PIVOT.VALUE(${generatePivotArgs(id, domain, measure).join(",")})`,
|
|
53690
|
+
value: formatValue(value, { format, locale }),
|
|
53691
|
+
isMissing: !this.tracker?.isValuePresent(measure, domain),
|
|
53692
|
+
});
|
|
53693
|
+
}
|
|
53694
|
+
values.push(current);
|
|
53695
|
+
}
|
|
53696
|
+
return values;
|
|
53697
|
+
}
|
|
53698
|
+
}
|
|
53699
|
+
|
|
53222
53700
|
/**
|
|
53223
53701
|
* BasePlugin
|
|
53224
53702
|
*
|
|
@@ -54569,7 +55047,7 @@ class ChartPlugin extends CorePlugin {
|
|
|
54569
55047
|
case "CREATE_CHART":
|
|
54570
55048
|
return this.checkValidations(cmd, this.chainValidations(this.validateChartDefinition, this.checkChartDuplicate));
|
|
54571
55049
|
case "UPDATE_CHART":
|
|
54572
|
-
return this.checkValidations(cmd, this.chainValidations(this.validateChartDefinition, this.checkChartExists));
|
|
55050
|
+
return this.checkValidations(cmd, this.chainValidations(this.validateChartDefinition, this.checkChartExists, this.checkChartChanged));
|
|
54573
55051
|
default:
|
|
54574
55052
|
return "Success" /* CommandResult.Success */;
|
|
54575
55053
|
}
|
|
@@ -54724,9 +55202,12 @@ class ChartPlugin extends CorePlugin {
|
|
|
54724
55202
|
: "Success" /* CommandResult.Success */;
|
|
54725
55203
|
}
|
|
54726
55204
|
checkChartExists(cmd) {
|
|
54727
|
-
return this.
|
|
54728
|
-
|
|
54729
|
-
|
|
55205
|
+
return this.isChartDefined(cmd.id) ? "Success" /* CommandResult.Success */ : "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
|
|
55206
|
+
}
|
|
55207
|
+
checkChartChanged(cmd) {
|
|
55208
|
+
return deepEquals(this.getChartDefinition(cmd.id), cmd.definition)
|
|
55209
|
+
? "NoChanges" /* CommandResult.NoChanges */
|
|
55210
|
+
: "Success" /* CommandResult.Success */;
|
|
54730
55211
|
}
|
|
54731
55212
|
}
|
|
54732
55213
|
|
|
@@ -56675,7 +57156,7 @@ class RangeAdapter {
|
|
|
56675
57156
|
if (range.sheetId === cmd.sheetId) {
|
|
56676
57157
|
return { changeType: "CHANGE", range };
|
|
56677
57158
|
}
|
|
56678
|
-
if (
|
|
57159
|
+
if (isSheetNameEqual(range.invalidSheetName, cmd.name)) {
|
|
56679
57160
|
const invalidSheetName = undefined;
|
|
56680
57161
|
const sheetId = cmd.sheetId;
|
|
56681
57162
|
const newRange = range.clone({ sheetId, invalidSheetName });
|
|
@@ -57045,6 +57526,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
57045
57526
|
"getCommandZones",
|
|
57046
57527
|
"getUnboundedZone",
|
|
57047
57528
|
"checkElementsIncludeAllNonFrozenHeaders",
|
|
57529
|
+
"getDuplicateSheetName",
|
|
57048
57530
|
];
|
|
57049
57531
|
sheetIdsMapName = {};
|
|
57050
57532
|
orderedSheetIds = [];
|
|
@@ -57069,7 +57551,11 @@ class SheetPlugin extends CorePlugin {
|
|
|
57069
57551
|
return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
|
|
57070
57552
|
}
|
|
57071
57553
|
case "DUPLICATE_SHEET": {
|
|
57072
|
-
|
|
57554
|
+
if (this.sheets[cmd.sheetIdTo])
|
|
57555
|
+
return "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */;
|
|
57556
|
+
if (this.orderedSheetIds.map(this.getSheetName.bind(this)).includes(cmd.sheetNameTo))
|
|
57557
|
+
return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
|
|
57558
|
+
return "Success" /* CommandResult.Success */;
|
|
57073
57559
|
}
|
|
57074
57560
|
case "MOVE_SHEET":
|
|
57075
57561
|
try {
|
|
@@ -57146,7 +57632,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
57146
57632
|
this.showSheet(cmd.sheetId);
|
|
57147
57633
|
break;
|
|
57148
57634
|
case "DUPLICATE_SHEET":
|
|
57149
|
-
this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo);
|
|
57635
|
+
this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo, cmd.sheetNameTo);
|
|
57150
57636
|
break;
|
|
57151
57637
|
case "DELETE_SHEET":
|
|
57152
57638
|
this.deleteSheet(this.sheets[cmd.sheetId]);
|
|
@@ -57287,7 +57773,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
57287
57773
|
if (name) {
|
|
57288
57774
|
const unquotedName = getUnquotedSheetName(name);
|
|
57289
57775
|
for (const key in this.sheetIdsMapName) {
|
|
57290
|
-
if (key
|
|
57776
|
+
if (isSheetNameEqual(key, unquotedName)) {
|
|
57291
57777
|
return this.sheetIdsMapName[key];
|
|
57292
57778
|
}
|
|
57293
57779
|
}
|
|
@@ -57353,10 +57839,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
57353
57839
|
}
|
|
57354
57840
|
getNextSheetName(baseName = "Sheet") {
|
|
57355
57841
|
const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
|
|
57356
|
-
return
|
|
57357
|
-
compute: (name, i) => `${name}${i}`,
|
|
57358
|
-
computeFirstOne: true,
|
|
57359
|
-
});
|
|
57842
|
+
return getNextSheetName(names, baseName);
|
|
57360
57843
|
}
|
|
57361
57844
|
getSheetSize(sheetId) {
|
|
57362
57845
|
return {
|
|
@@ -57538,7 +58021,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
57538
58021
|
}
|
|
57539
58022
|
const { orderedSheetIds, sheets } = this;
|
|
57540
58023
|
const name = cmd.name && cmd.name.trim().toLowerCase();
|
|
57541
|
-
if (orderedSheetIds.find((id) => sheets[id]?.name
|
|
58024
|
+
if (orderedSheetIds.find((id) => isSheetNameEqual(sheets[id]?.name, name) && id !== cmd.sheetId)) {
|
|
57542
58025
|
return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
|
|
57543
58026
|
}
|
|
57544
58027
|
if (FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX.test(name)) {
|
|
@@ -57602,9 +58085,8 @@ class SheetPlugin extends CorePlugin {
|
|
|
57602
58085
|
showSheet(sheetId) {
|
|
57603
58086
|
this.history.update("sheets", sheetId, "isVisible", true);
|
|
57604
58087
|
}
|
|
57605
|
-
duplicateSheet(fromId, toId) {
|
|
58088
|
+
duplicateSheet(fromId, toId, toName) {
|
|
57606
58089
|
const sheet = this.getSheet(fromId);
|
|
57607
|
-
const toName = this.getDuplicateSheetName(sheet.name);
|
|
57608
58090
|
const newSheet = deepCopy(sheet);
|
|
57609
58091
|
newSheet.id = toId;
|
|
57610
58092
|
newSheet.name = toName;
|
|
@@ -57637,8 +58119,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
57637
58119
|
}
|
|
57638
58120
|
getDuplicateSheetName(sheetName) {
|
|
57639
58121
|
const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
|
|
57640
|
-
|
|
57641
|
-
return getUniqueText(baseName.toString(), names);
|
|
58122
|
+
return getDuplicateSheetName(sheetName, names);
|
|
57642
58123
|
}
|
|
57643
58124
|
deleteSheet(sheet) {
|
|
57644
58125
|
const name = sheet.name;
|
|
@@ -60433,8 +60914,8 @@ class SpreadingRelation {
|
|
|
60433
60914
|
const EMPTY_ARRAY = [];
|
|
60434
60915
|
|
|
60435
60916
|
const MAX_ITERATION = 30;
|
|
60436
|
-
const ERROR_CYCLE_CELL = createEvaluatedCell(new CircularDependencyError());
|
|
60437
|
-
const EMPTY_CELL = createEvaluatedCell({ value: null });
|
|
60917
|
+
const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell(new CircularDependencyError()));
|
|
60918
|
+
const EMPTY_CELL = Object.freeze(createEvaluatedCell({ value: null }));
|
|
60438
60919
|
class Evaluator {
|
|
60439
60920
|
context;
|
|
60440
60921
|
getters;
|
|
@@ -66433,6 +66914,55 @@ class HistoryPlugin extends UIPlugin {
|
|
|
66433
66914
|
}
|
|
66434
66915
|
}
|
|
66435
66916
|
|
|
66917
|
+
class PivotPresenceTracker {
|
|
66918
|
+
trackedValues = new Set();
|
|
66919
|
+
domainToArray(domain) {
|
|
66920
|
+
return domain.flatMap((node) => [node.field, toString(node.value)]);
|
|
66921
|
+
}
|
|
66922
|
+
isValuePresent(measure, domain) {
|
|
66923
|
+
const key = JSON.stringify({ measure, domain: this.domainToArray(domain) });
|
|
66924
|
+
return this.trackedValues.has(key);
|
|
66925
|
+
}
|
|
66926
|
+
isHeaderPresent(domain) {
|
|
66927
|
+
const key = JSON.stringify({ domain: this.domainToArray(domain) });
|
|
66928
|
+
return this.trackedValues.has(key);
|
|
66929
|
+
}
|
|
66930
|
+
trackValue(measure, domain) {
|
|
66931
|
+
const key = JSON.stringify({ measure, domain: this.domainToArray(domain) });
|
|
66932
|
+
this.trackedValues.add(key);
|
|
66933
|
+
}
|
|
66934
|
+
trackHeader(domain) {
|
|
66935
|
+
const key = JSON.stringify({ domain: this.domainToArray(domain) });
|
|
66936
|
+
this.trackedValues.add(key);
|
|
66937
|
+
}
|
|
66938
|
+
}
|
|
66939
|
+
|
|
66940
|
+
class PivotPresencePlugin extends UIPlugin {
|
|
66941
|
+
static getters = ["getPivotPresenceTracker"];
|
|
66942
|
+
trackPresencePivotId;
|
|
66943
|
+
tracker;
|
|
66944
|
+
handle(cmd) {
|
|
66945
|
+
switch (cmd.type) {
|
|
66946
|
+
case "PIVOT_START_PRESENCE_TRACKING":
|
|
66947
|
+
this.tracker = new PivotPresenceTracker();
|
|
66948
|
+
this.trackPresencePivotId = cmd.pivotId;
|
|
66949
|
+
break;
|
|
66950
|
+
case "PIVOT_STOP_PRESENCE_TRACKING":
|
|
66951
|
+
this.trackPresencePivotId = undefined;
|
|
66952
|
+
break;
|
|
66953
|
+
}
|
|
66954
|
+
}
|
|
66955
|
+
getPivotPresenceTracker(pivotId) {
|
|
66956
|
+
if (this.trackPresencePivotId !== pivotId) {
|
|
66957
|
+
return undefined;
|
|
66958
|
+
}
|
|
66959
|
+
if (!this.tracker) {
|
|
66960
|
+
throw new Error("Tracker not initialized");
|
|
66961
|
+
}
|
|
66962
|
+
return this.tracker;
|
|
66963
|
+
}
|
|
66964
|
+
}
|
|
66965
|
+
|
|
66436
66966
|
class SplitToColumnsPlugin extends UIPlugin {
|
|
66437
66967
|
static getters = ["getAutomaticSeparator"];
|
|
66438
66968
|
allowDispatch(cmd) {
|
|
@@ -69183,6 +69713,7 @@ const featurePluginRegistry = new Registry()
|
|
|
69183
69713
|
.add("automatic_sum", AutomaticSumPlugin)
|
|
69184
69714
|
.add("format", FormatPlugin)
|
|
69185
69715
|
.add("insert_pivot", InsertPivotPlugin)
|
|
69716
|
+
.add("pivot_presence", PivotPresencePlugin)
|
|
69186
69717
|
.add("split_to_columns", SplitToColumnsPlugin)
|
|
69187
69718
|
.add("collaborative", CollaborativePlugin)
|
|
69188
69719
|
.add("history", HistoryPlugin)
|
|
@@ -69563,11 +70094,11 @@ class BottomBarSheet extends owl.Component {
|
|
|
69563
70094
|
if (ev.key === "Enter") {
|
|
69564
70095
|
ev.preventDefault();
|
|
69565
70096
|
this.stopEdition();
|
|
69566
|
-
this.DOMFocusableElementStore.
|
|
70097
|
+
this.DOMFocusableElementStore.focus();
|
|
69567
70098
|
}
|
|
69568
70099
|
if (ev.key === "Escape") {
|
|
69569
70100
|
this.cancelEdition();
|
|
69570
|
-
this.DOMFocusableElementStore.
|
|
70101
|
+
this.DOMFocusableElementStore.focus();
|
|
69571
70102
|
}
|
|
69572
70103
|
}
|
|
69573
70104
|
onMouseEventSheetName(ev) {
|
|
@@ -71739,11 +72270,13 @@ class Spreadsheet extends owl.Component {
|
|
|
71739
72270
|
this.checkViewportSize();
|
|
71740
72271
|
stores.on("store-updated", this, render);
|
|
71741
72272
|
resizeObserver.observe(this.spreadsheetRef.el);
|
|
72273
|
+
registerChartJSExtensions();
|
|
71742
72274
|
});
|
|
71743
72275
|
owl.onWillUnmount(() => {
|
|
71744
72276
|
this.unbindModelEvents();
|
|
71745
72277
|
stores.off("store-updated", this);
|
|
71746
72278
|
resizeObserver.disconnect();
|
|
72279
|
+
unregisterChartJsExtensions();
|
|
71747
72280
|
});
|
|
71748
72281
|
owl.onPatched(() => {
|
|
71749
72282
|
this.checkViewportSize();
|
|
@@ -76176,6 +76709,7 @@ const components = {
|
|
|
76176
76709
|
PivotDimensionOrder,
|
|
76177
76710
|
PivotDimension,
|
|
76178
76711
|
PivotLayoutConfigurator,
|
|
76712
|
+
PivotHTMLRenderer,
|
|
76179
76713
|
PivotDeferUpdate,
|
|
76180
76714
|
PivotTitleSection,
|
|
76181
76715
|
CogWheelMenu,
|
|
@@ -76270,6 +76804,6 @@ exports.tokenColors = tokenColors;
|
|
|
76270
76804
|
exports.tokenize = tokenize;
|
|
76271
76805
|
|
|
76272
76806
|
|
|
76273
|
-
__info__.version = "18.2.
|
|
76274
|
-
__info__.date = "2025-05-
|
|
76275
|
-
__info__.hash = "
|
|
76807
|
+
__info__.version = "18.2.12";
|
|
76808
|
+
__info__.date = "2025-05-13T17:52:23.989Z";
|
|
76809
|
+
__info__.hash = "ba2ba9b";
|