@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
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -3357,7 +3357,7 @@ function isDateAfter(date, dateAfter) {
|
|
|
3357
3357
|
*/
|
|
3358
3358
|
const getFormulaNumberRegex = memoize(function getFormulaNumberRegex(decimalSeparator) {
|
|
3359
3359
|
decimalSeparator = escapeRegExp(decimalSeparator);
|
|
3360
|
-
return new RegExp(`(?:^-?\\d+(?:${decimalSeparator}?\\d*(?:e
|
|
3360
|
+
return new RegExp(`(?:^-?\\d+(?:${decimalSeparator}?\\d*(?:e(\\+|-)?\\d+)?)?|^-?${decimalSeparator}\\d+)(?!\\w|!)`);
|
|
3361
3361
|
});
|
|
3362
3362
|
const getNumberRegex = memoize(function getNumberRegex(locale) {
|
|
3363
3363
|
const decimalSeparator = escapeRegExp(locale.decimalSeparator);
|
|
@@ -6280,6 +6280,32 @@ function moveHeaderIndexesOnHeaderDeletion(deletedHeaders, headers) {
|
|
|
6280
6280
|
})
|
|
6281
6281
|
.filter(isDefined);
|
|
6282
6282
|
}
|
|
6283
|
+
function getNextSheetName(existingNames, baseName = "Sheet") {
|
|
6284
|
+
let i = 1;
|
|
6285
|
+
let name = `${baseName}${i}`;
|
|
6286
|
+
while (existingNames.includes(name)) {
|
|
6287
|
+
name = `${baseName}${i}`;
|
|
6288
|
+
i++;
|
|
6289
|
+
}
|
|
6290
|
+
return name;
|
|
6291
|
+
}
|
|
6292
|
+
function getDuplicateSheetName(nameToDuplicate, existingNames) {
|
|
6293
|
+
let i = 1;
|
|
6294
|
+
const baseName = _t("Copy of %s", nameToDuplicate);
|
|
6295
|
+
let name = baseName.toString();
|
|
6296
|
+
while (existingNames.includes(name)) {
|
|
6297
|
+
name = `${baseName} (${i})`;
|
|
6298
|
+
i++;
|
|
6299
|
+
}
|
|
6300
|
+
return name;
|
|
6301
|
+
}
|
|
6302
|
+
function isSheetNameEqual(name1, name2) {
|
|
6303
|
+
if (name1 === undefined || name2 === undefined) {
|
|
6304
|
+
return false;
|
|
6305
|
+
}
|
|
6306
|
+
return (getUnquotedSheetName(name1.trim().toUpperCase()) ===
|
|
6307
|
+
getUnquotedSheetName(name2.trim().toUpperCase()));
|
|
6308
|
+
}
|
|
6283
6309
|
|
|
6284
6310
|
function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
|
|
6285
6311
|
return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
|
|
@@ -7978,6 +8004,24 @@ const monthNumberAdapter = {
|
|
|
7978
8004
|
return `${normalizedValue}`;
|
|
7979
8005
|
},
|
|
7980
8006
|
};
|
|
8007
|
+
/**
|
|
8008
|
+
* normalizes month number + year
|
|
8009
|
+
*/
|
|
8010
|
+
const monthAdapter = {
|
|
8011
|
+
normalizeFunctionValue(value) {
|
|
8012
|
+
const date = toNumber(value, DEFAULT_LOCALE);
|
|
8013
|
+
return formatValue(date, { locale: DEFAULT_LOCALE, format: "mm/yyyy" });
|
|
8014
|
+
},
|
|
8015
|
+
toValueAndFormat(normalizedValue) {
|
|
8016
|
+
return {
|
|
8017
|
+
value: toNumber(normalizedValue, DEFAULT_LOCALE),
|
|
8018
|
+
format: "mmmm yyyy",
|
|
8019
|
+
};
|
|
8020
|
+
},
|
|
8021
|
+
toFunctionValue(normalizedValue) {
|
|
8022
|
+
return `"${normalizedValue}"`;
|
|
8023
|
+
},
|
|
8024
|
+
};
|
|
7981
8025
|
/**
|
|
7982
8026
|
* normalizes quarter number
|
|
7983
8027
|
*/
|
|
@@ -8108,6 +8152,7 @@ pivotTimeAdapterRegistry
|
|
|
8108
8152
|
.add("day_of_month", nullHandlerDecorator(dayOfMonthAdapter))
|
|
8109
8153
|
.add("iso_week_number", nullHandlerDecorator(isoWeekNumberAdapter))
|
|
8110
8154
|
.add("month_number", nullHandlerDecorator(monthNumberAdapter))
|
|
8155
|
+
.add("month", nullHandlerDecorator(monthAdapter))
|
|
8111
8156
|
.add("quarter_number", nullHandlerDecorator(quarterNumberAdapter))
|
|
8112
8157
|
.add("day_of_week", nullHandlerDecorator(dayOfWeekAdapter))
|
|
8113
8158
|
.add("hour_number", nullHandlerDecorator(hourNumberAdapter))
|
|
@@ -8124,10 +8169,9 @@ const AGGREGATOR_NAMES = {
|
|
|
8124
8169
|
avg: _t("Average"),
|
|
8125
8170
|
sum: _t("Sum"),
|
|
8126
8171
|
};
|
|
8127
|
-
const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
|
|
8128
8172
|
const AGGREGATORS_BY_FIELD_TYPE = {
|
|
8129
|
-
integer:
|
|
8130
|
-
char:
|
|
8173
|
+
integer: ["max", "min", "avg", "sum", "count_distinct", "count"],
|
|
8174
|
+
char: ["count_distinct", "count"],
|
|
8131
8175
|
boolean: ["count_distinct", "count", "bool_and", "bool_or"],
|
|
8132
8176
|
datetime: ["max", "min", "count_distinct", "count"],
|
|
8133
8177
|
};
|
|
@@ -8288,10 +8332,7 @@ function toNormalizedPivotValue(dimension, groupValue) {
|
|
|
8288
8332
|
return normalizer(groupValueString, dimension.granularity);
|
|
8289
8333
|
}
|
|
8290
8334
|
function normalizeDateTime(value, granularity) {
|
|
8291
|
-
|
|
8292
|
-
throw new Error("Missing granularity");
|
|
8293
|
-
}
|
|
8294
|
-
return pivotTimeAdapter(granularity).normalizeFunctionValue(value);
|
|
8335
|
+
return pivotTimeAdapter(granularity ?? "month").normalizeFunctionValue(value);
|
|
8295
8336
|
}
|
|
8296
8337
|
function toFunctionPivotValue(value, dimension) {
|
|
8297
8338
|
if (value === null) {
|
|
@@ -8303,10 +8344,7 @@ function toFunctionPivotValue(value, dimension) {
|
|
|
8303
8344
|
return pivotToFunctionValueRegistry.get(dimension.type)(value, dimension.granularity);
|
|
8304
8345
|
}
|
|
8305
8346
|
function toFunctionValueDateTime(value, granularity) {
|
|
8306
|
-
|
|
8307
|
-
throw new Error("Missing granularity");
|
|
8308
|
-
}
|
|
8309
|
-
return pivotTimeAdapter(granularity).toFunctionValue(value);
|
|
8347
|
+
return pivotTimeAdapter(granularity ?? "month").toFunctionValue(value);
|
|
8310
8348
|
}
|
|
8311
8349
|
const pivotNormalizationValueRegistry = new Registry();
|
|
8312
8350
|
pivotNormalizationValueRegistry
|
|
@@ -9486,7 +9524,10 @@ function proxifyStoreMutation(store, callback) {
|
|
|
9486
9524
|
const functionProxy = new Proxy(value, {
|
|
9487
9525
|
// trap the function call
|
|
9488
9526
|
apply(target, thisArg, argArray) {
|
|
9489
|
-
Reflect.apply(target, thisStore, argArray);
|
|
9527
|
+
const res = Reflect.apply(target, thisStore, argArray);
|
|
9528
|
+
if (res === "noStateChange") {
|
|
9529
|
+
return;
|
|
9530
|
+
}
|
|
9490
9531
|
callback();
|
|
9491
9532
|
},
|
|
9492
9533
|
});
|
|
@@ -9508,7 +9549,7 @@ function getDependencyContainer(env) {
|
|
|
9508
9549
|
const ModelStore = createAbstractStore("Model");
|
|
9509
9550
|
|
|
9510
9551
|
class RendererStore {
|
|
9511
|
-
mutators = ["register", "unRegister"];
|
|
9552
|
+
mutators = ["register", "unRegister", "drawLayer"];
|
|
9512
9553
|
renderers = {};
|
|
9513
9554
|
register(renderer) {
|
|
9514
9555
|
if (!renderer.renderingLayers.length) {
|
|
@@ -9528,14 +9569,14 @@ class RendererStore {
|
|
|
9528
9569
|
}
|
|
9529
9570
|
drawLayer(context, layer) {
|
|
9530
9571
|
const renderers = this.renderers[layer];
|
|
9531
|
-
if (
|
|
9532
|
-
|
|
9533
|
-
|
|
9534
|
-
|
|
9535
|
-
|
|
9536
|
-
|
|
9537
|
-
context.ctx.restore();
|
|
9572
|
+
if (renderers) {
|
|
9573
|
+
for (const renderer of renderers) {
|
|
9574
|
+
context.ctx.save();
|
|
9575
|
+
renderer.drawLayer(context, layer);
|
|
9576
|
+
context.ctx.restore();
|
|
9577
|
+
}
|
|
9538
9578
|
}
|
|
9579
|
+
return "noStateChange";
|
|
9539
9580
|
}
|
|
9540
9581
|
}
|
|
9541
9582
|
|
|
@@ -9588,16 +9629,17 @@ class ComposerFocusStore extends SpreadsheetStore {
|
|
|
9588
9629
|
focusComposer(listener, args) {
|
|
9589
9630
|
this.activeComposer = listener;
|
|
9590
9631
|
if (this.getters.isReadonly()) {
|
|
9591
|
-
return;
|
|
9632
|
+
return "noStateChange";
|
|
9592
9633
|
}
|
|
9593
9634
|
this._focusMode = args.focusMode || "contentFocus";
|
|
9594
9635
|
if (this._focusMode !== "inactive") {
|
|
9595
9636
|
this.setComposerContent(args);
|
|
9596
9637
|
}
|
|
9638
|
+
return;
|
|
9597
9639
|
}
|
|
9598
9640
|
focusActiveComposer(args) {
|
|
9599
9641
|
if (this.getters.isReadonly()) {
|
|
9600
|
-
return;
|
|
9642
|
+
return "noStateChange";
|
|
9601
9643
|
}
|
|
9602
9644
|
if (!this.activeComposer) {
|
|
9603
9645
|
throw new Error("No composer is registered");
|
|
@@ -9606,6 +9648,7 @@ class ComposerFocusStore extends SpreadsheetStore {
|
|
|
9606
9648
|
if (this._focusMode !== "inactive") {
|
|
9607
9649
|
this.setComposerContent(args);
|
|
9608
9650
|
}
|
|
9651
|
+
return;
|
|
9609
9652
|
}
|
|
9610
9653
|
/**
|
|
9611
9654
|
* Start the edition or update the content if it's already started.
|
|
@@ -9765,12 +9808,24 @@ function getElementMargins(el) {
|
|
|
9765
9808
|
}
|
|
9766
9809
|
|
|
9767
9810
|
const chartJsExtensionRegistry = new Registry();
|
|
9768
|
-
|
|
9769
|
-
|
|
9770
|
-
|
|
9771
|
-
|
|
9811
|
+
function areChartJSExtensionsLoaded() {
|
|
9812
|
+
return !!window.Chart.registry.plugins.get("chartShowValuesPlugin");
|
|
9813
|
+
}
|
|
9814
|
+
function registerChartJSExtensions() {
|
|
9815
|
+
if (!window.Chart || areChartJSExtensionsLoaded()) {
|
|
9816
|
+
return;
|
|
9817
|
+
}
|
|
9818
|
+
for (const registryItem of chartJsExtensionRegistry.getAll()) {
|
|
9819
|
+
registryItem.register(window.Chart);
|
|
9820
|
+
}
|
|
9821
|
+
}
|
|
9822
|
+
function unregisterChartJsExtensions() {
|
|
9823
|
+
if (!window.Chart) {
|
|
9824
|
+
return;
|
|
9825
|
+
}
|
|
9826
|
+
for (const registryItem of chartJsExtensionRegistry.getAll()) {
|
|
9827
|
+
registryItem.unregister(window.Chart);
|
|
9772
9828
|
}
|
|
9773
|
-
return window.Chart;
|
|
9774
9829
|
}
|
|
9775
9830
|
|
|
9776
9831
|
const TREND_LINE_XAXIS_ID = "x1";
|
|
@@ -10087,7 +10142,7 @@ function getDefinedAxis(definition) {
|
|
|
10087
10142
|
}
|
|
10088
10143
|
function formatChartDatasetValue(axisFormats, locale) {
|
|
10089
10144
|
return (value, axisId) => {
|
|
10090
|
-
const format =
|
|
10145
|
+
const format = axisFormats?.[axisId];
|
|
10091
10146
|
return formatTickValue({ format, locale })(value);
|
|
10092
10147
|
};
|
|
10093
10148
|
}
|
|
@@ -10261,7 +10316,7 @@ function drawPieChartValues(chart, options, ctx) {
|
|
|
10261
10316
|
const y = bar.y + midRadius * Math.sin(midAngle) + 7;
|
|
10262
10317
|
ctx.fillStyle = chartFontColor(options.background);
|
|
10263
10318
|
ctx.strokeStyle = options.background || "#ffffff";
|
|
10264
|
-
const displayValue = options.callback(value);
|
|
10319
|
+
const displayValue = options.callback(value, "y");
|
|
10265
10320
|
drawTextWithBackground(displayValue, x, y, ctx);
|
|
10266
10321
|
}
|
|
10267
10322
|
}
|
|
@@ -10330,8 +10385,14 @@ css /* scss */ `
|
|
|
10330
10385
|
}
|
|
10331
10386
|
}
|
|
10332
10387
|
`;
|
|
10333
|
-
chartJsExtensionRegistry.add("chartShowValuesPlugin",
|
|
10334
|
-
|
|
10388
|
+
chartJsExtensionRegistry.add("chartShowValuesPlugin", {
|
|
10389
|
+
register: (Chart) => Chart.register(chartShowValuesPlugin),
|
|
10390
|
+
unregister: (Chart) => Chart.unregister(chartShowValuesPlugin),
|
|
10391
|
+
});
|
|
10392
|
+
chartJsExtensionRegistry.add("waterfallLinesPlugin", {
|
|
10393
|
+
register: (Chart) => Chart.register(waterfallLinesPlugin),
|
|
10394
|
+
unregister: (Chart) => Chart.unregister(waterfallLinesPlugin),
|
|
10395
|
+
});
|
|
10335
10396
|
class ChartJsComponent extends Component {
|
|
10336
10397
|
static template = "o-spreadsheet-ChartJsComponent";
|
|
10337
10398
|
static props = {
|
|
@@ -10383,8 +10444,7 @@ class ChartJsComponent extends Component {
|
|
|
10383
10444
|
createChart(chartData) {
|
|
10384
10445
|
const canvas = this.canvas.el;
|
|
10385
10446
|
const ctx = canvas.getContext("2d");
|
|
10386
|
-
|
|
10387
|
-
this.chart = new Chart(ctx, chartData);
|
|
10447
|
+
this.chart = new window.Chart(ctx, chartData);
|
|
10388
10448
|
}
|
|
10389
10449
|
updateChartJs(chartData) {
|
|
10390
10450
|
if (chartData.data && chartData.data.datasets) {
|
|
@@ -18516,7 +18576,7 @@ const IF = {
|
|
|
18516
18576
|
return { value: "" };
|
|
18517
18577
|
}
|
|
18518
18578
|
if (result.value === null) {
|
|
18519
|
-
result
|
|
18579
|
+
return { ...result, value: "" };
|
|
18520
18580
|
}
|
|
18521
18581
|
return result;
|
|
18522
18582
|
},
|
|
@@ -18537,7 +18597,7 @@ const IFERROR = {
|
|
|
18537
18597
|
return { value: "" };
|
|
18538
18598
|
}
|
|
18539
18599
|
if (result.value === null) {
|
|
18540
|
-
result
|
|
18600
|
+
return { ...result, value: "" };
|
|
18541
18601
|
}
|
|
18542
18602
|
return result;
|
|
18543
18603
|
},
|
|
@@ -18558,7 +18618,7 @@ const IFNA = {
|
|
|
18558
18618
|
return { value: "" };
|
|
18559
18619
|
}
|
|
18560
18620
|
if (result.value === null) {
|
|
18561
|
-
result
|
|
18621
|
+
return { ...result, value: "" };
|
|
18562
18622
|
}
|
|
18563
18623
|
return result;
|
|
18564
18624
|
},
|
|
@@ -18584,7 +18644,7 @@ const IFS = {
|
|
|
18584
18644
|
return { value: "" };
|
|
18585
18645
|
}
|
|
18586
18646
|
if (result.value === null) {
|
|
18587
|
-
result
|
|
18647
|
+
return { ...result, value: "" };
|
|
18588
18648
|
}
|
|
18589
18649
|
return result;
|
|
18590
18650
|
}
|
|
@@ -18702,6 +18762,11 @@ function addPivotDependencies(evalContext, coreDefinition, forMeasures) {
|
|
|
18702
18762
|
if (range === undefined || range.invalidXc || range.invalidSheetName) {
|
|
18703
18763
|
throw new InvalidReferenceError();
|
|
18704
18764
|
}
|
|
18765
|
+
if (evalContext.__originCellPosition &&
|
|
18766
|
+
range.sheetId === evalContext.__originSheetId &&
|
|
18767
|
+
isZoneInside(positionToZone(evalContext.__originCellPosition), zone)) {
|
|
18768
|
+
throw new CircularDependencyError();
|
|
18769
|
+
}
|
|
18705
18770
|
dependencies.push(range);
|
|
18706
18771
|
}
|
|
18707
18772
|
for (const measure of forMeasures) {
|
|
@@ -19150,6 +19215,9 @@ const PIVOT_VALUE = {
|
|
|
19150
19215
|
};
|
|
19151
19216
|
}
|
|
19152
19217
|
const domain = pivot.parseArgsToPivotDomain(domainArgs);
|
|
19218
|
+
if (this.getters.getActiveSheetId() === this.__originSheetId) {
|
|
19219
|
+
this.getters.getPivotPresenceTracker(pivotId)?.trackValue(_measure, domain);
|
|
19220
|
+
}
|
|
19153
19221
|
return pivot.getPivotCellValueAndFormat(_measure, domain);
|
|
19154
19222
|
},
|
|
19155
19223
|
};
|
|
@@ -19181,6 +19249,9 @@ const PIVOT_HEADER = {
|
|
|
19181
19249
|
};
|
|
19182
19250
|
}
|
|
19183
19251
|
const domain = pivot.parseArgsToPivotDomain(domainArgs);
|
|
19252
|
+
if (this.getters.getActiveSheetId() === this.__originSheetId) {
|
|
19253
|
+
this.getters.getPivotPresenceTracker(_pivotId)?.trackHeader(domain);
|
|
19254
|
+
}
|
|
19184
19255
|
const lastNode = domain.at(-1);
|
|
19185
19256
|
if (lastNode?.field === "measure") {
|
|
19186
19257
|
return pivot.getPivotMeasureValue(toString(lastNode.value), domain);
|
|
@@ -19403,6 +19474,9 @@ function isEmpty(data) {
|
|
|
19403
19474
|
return data === undefined || data.value === null;
|
|
19404
19475
|
}
|
|
19405
19476
|
const getNeutral = { number: 0, string: "", boolean: false };
|
|
19477
|
+
function areAlmostEqual(value1, value2, epsilon = 2e-16) {
|
|
19478
|
+
return Math.abs(value1 - value2) < epsilon;
|
|
19479
|
+
}
|
|
19406
19480
|
const EQ = {
|
|
19407
19481
|
description: _t("Equal."),
|
|
19408
19482
|
args: [
|
|
@@ -19424,6 +19498,9 @@ const EQ = {
|
|
|
19424
19498
|
if (typeof _value2 === "string") {
|
|
19425
19499
|
_value2 = _value2.toUpperCase();
|
|
19426
19500
|
}
|
|
19501
|
+
if (typeof _value1 === "number" && typeof _value2 === "number") {
|
|
19502
|
+
return { value: areAlmostEqual(_value1, _value2) };
|
|
19503
|
+
}
|
|
19427
19504
|
return { value: _value1 === _value2 };
|
|
19428
19505
|
},
|
|
19429
19506
|
};
|
|
@@ -19463,6 +19540,9 @@ const GT = {
|
|
|
19463
19540
|
],
|
|
19464
19541
|
compute: function (value1, value2) {
|
|
19465
19542
|
return applyRelationalOperator(value1, value2, (v1, v2) => {
|
|
19543
|
+
if (typeof v1 === "number" && typeof v2 === "number") {
|
|
19544
|
+
return !areAlmostEqual(v1, v2) && v1 > v2;
|
|
19545
|
+
}
|
|
19466
19546
|
return v1 > v2;
|
|
19467
19547
|
});
|
|
19468
19548
|
},
|
|
@@ -19478,6 +19558,9 @@ const GTE = {
|
|
|
19478
19558
|
],
|
|
19479
19559
|
compute: function (value1, value2) {
|
|
19480
19560
|
return applyRelationalOperator(value1, value2, (v1, v2) => {
|
|
19561
|
+
if (typeof v1 === "number" && typeof v2 === "number") {
|
|
19562
|
+
return areAlmostEqual(v1, v2) || v1 > v2;
|
|
19563
|
+
}
|
|
19481
19564
|
return v1 >= v2;
|
|
19482
19565
|
});
|
|
19483
19566
|
},
|
|
@@ -21084,7 +21167,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
21084
21167
|
.find((token) => {
|
|
21085
21168
|
const { xc, sheetName: sheet } = splitReference(token.value);
|
|
21086
21169
|
const sheetName = sheet || this.getters.getSheetName(this.sheetId);
|
|
21087
|
-
if (this.getters.getSheetName(activeSheetId)
|
|
21170
|
+
if (!isSheetNameEqual(this.getters.getSheetName(activeSheetId), sheetName)) {
|
|
21088
21171
|
return false;
|
|
21089
21172
|
}
|
|
21090
21173
|
const refRange = this.getters.getRangeFromSheetXC(activeSheetId, xc);
|
|
@@ -22963,6 +23046,7 @@ const CHART_COMMON_OPTIONS = {
|
|
|
22963
23046
|
},
|
|
22964
23047
|
},
|
|
22965
23048
|
animation: false,
|
|
23049
|
+
events: ["mousemove", "mouseout", "click", "touchstart", "touchmove", "mouseup"],
|
|
22966
23050
|
};
|
|
22967
23051
|
function chartToImage(runtime, figure, type) {
|
|
22968
23052
|
// wrap the canvas in a div with a fixed size because chart.js would
|
|
@@ -22979,8 +23063,7 @@ function chartToImage(runtime, figure, type) {
|
|
|
22979
23063
|
if ("chartJsConfig" in runtime) {
|
|
22980
23064
|
const config = deepCopy(runtime.chartJsConfig);
|
|
22981
23065
|
config.plugins = [backgroundColorChartJSPlugin];
|
|
22982
|
-
const
|
|
22983
|
-
const chart = new Chart(canvas, config);
|
|
23066
|
+
const chart = new window.Chart(canvas, config);
|
|
22984
23067
|
const imgContent = chart.toBase64Image();
|
|
22985
23068
|
chart.destroy();
|
|
22986
23069
|
div.remove();
|
|
@@ -24546,7 +24629,7 @@ function getRangeSize(reference, defaultSheetIndex, data) {
|
|
|
24546
24629
|
({ xc, sheetName } = splitReference(reference));
|
|
24547
24630
|
let rangeSheetIndex;
|
|
24548
24631
|
if (sheetName) {
|
|
24549
|
-
const index = data.sheets.findIndex((sheet) => sheet.name
|
|
24632
|
+
const index = data.sheets.findIndex((sheet) => isSheetNameEqual(sheet.name, sheetName));
|
|
24550
24633
|
if (index < 0) {
|
|
24551
24634
|
throw new Error("Unable to find a sheet with the name " + sheetName);
|
|
24552
24635
|
}
|
|
@@ -24887,7 +24970,7 @@ function convertFormula(formula, data) {
|
|
|
24887
24970
|
formula = formula.replace(externalReferenceRegex, (match, externalRefId, sheetName, cellRef) => {
|
|
24888
24971
|
externalRefId = Number(externalRefId) - 1;
|
|
24889
24972
|
cellRef = cellRef.replace(/\$/g, "");
|
|
24890
|
-
const sheetIndex = data.externalBooks[externalRefId].sheetNames.findIndex((name) => name
|
|
24973
|
+
const sheetIndex = data.externalBooks[externalRefId].sheetNames.findIndex((name) => isSheetNameEqual(name, sheetName));
|
|
24891
24974
|
if (sheetIndex === -1) {
|
|
24892
24975
|
return match;
|
|
24893
24976
|
}
|
|
@@ -25538,7 +25621,7 @@ function convertPivotTableConfig(pivotTable) {
|
|
|
25538
25621
|
*/
|
|
25539
25622
|
function convertTableFormulaReferences(convertedSheets, xlsxSheets) {
|
|
25540
25623
|
for (let tableSheet of convertedSheets) {
|
|
25541
|
-
const tables = xlsxSheets.find((s) => s.sheetName
|
|
25624
|
+
const tables = xlsxSheets.find((s) => isSheetNameEqual(s.sheetName, tableSheet.name)).tables;
|
|
25542
25625
|
for (let table of tables) {
|
|
25543
25626
|
const tabRef = table.name + "[";
|
|
25544
25627
|
for (let sheet of convertedSheets) {
|
|
@@ -27973,6 +28056,7 @@ function repairInitialMessages(data, initialMessages) {
|
|
|
27973
28056
|
initialMessages = dropCommands(initialMessages, "SORT_CELLS");
|
|
27974
28057
|
initialMessages = dropCommands(initialMessages, "SET_DECIMAL");
|
|
27975
28058
|
initialMessages = fixChartDefinitions(data, initialMessages);
|
|
28059
|
+
initialMessages = fixTranslatedDuplicateSheetName(data, initialMessages);
|
|
27976
28060
|
return initialMessages;
|
|
27977
28061
|
}
|
|
27978
28062
|
/**
|
|
@@ -28072,6 +28156,40 @@ function fixChartDefinitions(data, initialMessages) {
|
|
|
28072
28156
|
}
|
|
28073
28157
|
return messages;
|
|
28074
28158
|
}
|
|
28159
|
+
function fixTranslatedDuplicateSheetName(data, initialMessages) {
|
|
28160
|
+
const sheetNames = {};
|
|
28161
|
+
for (const sheet of data.sheets || []) {
|
|
28162
|
+
sheetNames[sheet.id] = sheet.name;
|
|
28163
|
+
}
|
|
28164
|
+
const messages = [];
|
|
28165
|
+
for (const message of initialMessages) {
|
|
28166
|
+
if (message.type === "REMOTE_REVISION") {
|
|
28167
|
+
const commands = [];
|
|
28168
|
+
for (const cmd of message.commands) {
|
|
28169
|
+
switch (cmd.type) {
|
|
28170
|
+
case "DUPLICATE_SHEET":
|
|
28171
|
+
cmd.sheetNameTo =
|
|
28172
|
+
cmd.sheetNameTo ??
|
|
28173
|
+
getDuplicateSheetName(sheetNames[cmd.sheetId], Object.values(sheetNames));
|
|
28174
|
+
break;
|
|
28175
|
+
case "CREATE_SHEET":
|
|
28176
|
+
case "RENAME_SHEET":
|
|
28177
|
+
sheetNames[cmd.sheetId] = cmd.name || getNextSheetName(Object.values(sheetNames));
|
|
28178
|
+
break;
|
|
28179
|
+
}
|
|
28180
|
+
commands.push(cmd);
|
|
28181
|
+
}
|
|
28182
|
+
messages.push({
|
|
28183
|
+
...message,
|
|
28184
|
+
commands,
|
|
28185
|
+
});
|
|
28186
|
+
}
|
|
28187
|
+
else {
|
|
28188
|
+
messages.push(message);
|
|
28189
|
+
}
|
|
28190
|
+
}
|
|
28191
|
+
return initialMessages;
|
|
28192
|
+
}
|
|
28075
28193
|
// -----------------------------------------------------------------------------
|
|
28076
28194
|
// Helpers
|
|
28077
28195
|
// -----------------------------------------------------------------------------
|
|
@@ -28868,12 +28986,11 @@ function canBeLinearChart(definition, dataSets, labelRange, getters) {
|
|
|
28868
28986
|
}
|
|
28869
28987
|
let missingTimeAdapterAlreadyWarned = false;
|
|
28870
28988
|
function isLuxonTimeAdapterInstalled() {
|
|
28871
|
-
|
|
28872
|
-
if (!Chart) {
|
|
28989
|
+
if (!window.Chart) {
|
|
28873
28990
|
return false;
|
|
28874
28991
|
}
|
|
28875
28992
|
// @ts-ignore
|
|
28876
|
-
const adapter = new Chart._adapters._date({});
|
|
28993
|
+
const adapter = new window.Chart._adapters._date({});
|
|
28877
28994
|
const isInstalled = adapter._id === "luxon";
|
|
28878
28995
|
if (!isInstalled && !missingTimeAdapterAlreadyWarned) {
|
|
28879
28996
|
missingTimeAdapterAlreadyWarned = true;
|
|
@@ -29511,6 +29628,9 @@ const INTERACTIVE_LEGEND_CONFIG = {
|
|
|
29511
29628
|
target.style.cursor = "default";
|
|
29512
29629
|
},
|
|
29513
29630
|
onClick: (event, legendItem, legend) => {
|
|
29631
|
+
if (event.type !== "click") {
|
|
29632
|
+
return;
|
|
29633
|
+
}
|
|
29514
29634
|
const index = legendItem.datasetIndex;
|
|
29515
29635
|
if (!legend.legendItems || index === undefined) {
|
|
29516
29636
|
return;
|
|
@@ -32493,12 +32613,20 @@ class HoveredCellStore extends SpreadsheetStore {
|
|
|
32493
32613
|
}
|
|
32494
32614
|
}
|
|
32495
32615
|
hover(position) {
|
|
32616
|
+
if (position.col === this.col && position.row === this.row) {
|
|
32617
|
+
return "noStateChange";
|
|
32618
|
+
}
|
|
32496
32619
|
this.col = position.col;
|
|
32497
32620
|
this.row = position.row;
|
|
32621
|
+
return;
|
|
32498
32622
|
}
|
|
32499
32623
|
clear() {
|
|
32624
|
+
if (this.col === undefined && this.row === undefined) {
|
|
32625
|
+
return "noStateChange";
|
|
32626
|
+
}
|
|
32500
32627
|
this.col = undefined;
|
|
32501
32628
|
this.row = undefined;
|
|
32629
|
+
return;
|
|
32502
32630
|
}
|
|
32503
32631
|
}
|
|
32504
32632
|
|
|
@@ -32520,7 +32648,11 @@ class CellPopoverStore extends SpreadsheetStore {
|
|
|
32520
32648
|
this.persistentPopover = { col, row, sheetId, type };
|
|
32521
32649
|
}
|
|
32522
32650
|
close() {
|
|
32651
|
+
if (!this.persistentPopover) {
|
|
32652
|
+
return "noStateChange";
|
|
32653
|
+
}
|
|
32523
32654
|
this.persistentPopover = undefined;
|
|
32655
|
+
return;
|
|
32524
32656
|
}
|
|
32525
32657
|
get persistentCellPopover() {
|
|
32526
32658
|
return ((this.persistentPopover && { isOpen: true, ...this.persistentPopover }) || { isOpen: false });
|
|
@@ -33410,10 +33542,13 @@ const duplicateSheet = {
|
|
|
33410
33542
|
name: _t("Duplicate"),
|
|
33411
33543
|
execute: (env) => {
|
|
33412
33544
|
const sheetIdFrom = env.model.getters.getActiveSheetId();
|
|
33545
|
+
const sheetNameFrom = env.model.getters.getSheetName(sheetIdFrom);
|
|
33413
33546
|
const sheetIdTo = env.model.uuidGenerator.smallUuid();
|
|
33547
|
+
const sheetNameTo = env.model.getters.getDuplicateSheetName(sheetNameFrom);
|
|
33414
33548
|
env.model.dispatch("DUPLICATE_SHEET", {
|
|
33415
33549
|
sheetId: sheetIdFrom,
|
|
33416
33550
|
sheetIdTo,
|
|
33551
|
+
sheetNameTo,
|
|
33417
33552
|
});
|
|
33418
33553
|
env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom, sheetIdTo });
|
|
33419
33554
|
},
|
|
@@ -38616,7 +38751,7 @@ class GenericChartConfigPanel extends Component {
|
|
|
38616
38751
|
const cancelledReasons = [
|
|
38617
38752
|
...(this.state.datasetDispatchResult?.reasons || []),
|
|
38618
38753
|
...(this.state.labelsDispatchResult?.reasons || []),
|
|
38619
|
-
];
|
|
38754
|
+
].filter((reason) => reason !== "NoChanges" /* CommandResult.NoChanges */);
|
|
38620
38755
|
return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
|
|
38621
38756
|
}
|
|
38622
38757
|
get isDatasetInvalid() {
|
|
@@ -39973,10 +40108,18 @@ class GaugeChartConfigPanel extends Component {
|
|
|
39973
40108
|
}
|
|
39974
40109
|
|
|
39975
40110
|
class DOMFocusableElementStore {
|
|
39976
|
-
mutators = ["setFocusableElement"];
|
|
40111
|
+
mutators = ["setFocusableElement", "focus"];
|
|
39977
40112
|
focusableElement = undefined;
|
|
39978
40113
|
setFocusableElement(element) {
|
|
39979
40114
|
this.focusableElement = element;
|
|
40115
|
+
return "noStateChange";
|
|
40116
|
+
}
|
|
40117
|
+
focus() {
|
|
40118
|
+
if (this.focusableElement === document.activeElement) {
|
|
40119
|
+
return "noStateChange";
|
|
40120
|
+
}
|
|
40121
|
+
this.focusableElement?.focus();
|
|
40122
|
+
return;
|
|
39980
40123
|
}
|
|
39981
40124
|
}
|
|
39982
40125
|
|
|
@@ -40564,7 +40707,7 @@ class Composer extends Component {
|
|
|
40564
40707
|
if (document.activeElement === this.contentHelper.el &&
|
|
40565
40708
|
this.props.composerStore.editionMode === "inactive" &&
|
|
40566
40709
|
!this.props.isDefaultFocus) {
|
|
40567
|
-
this.DOMFocusableElementStore.
|
|
40710
|
+
this.DOMFocusableElementStore.focus();
|
|
40568
40711
|
}
|
|
40569
40712
|
});
|
|
40570
40713
|
useEffect(() => {
|
|
@@ -40838,6 +40981,13 @@ class Composer extends Component {
|
|
|
40838
40981
|
openAssistant() {
|
|
40839
40982
|
this.assistant.forcedClosed = false;
|
|
40840
40983
|
}
|
|
40984
|
+
onWheel(event) {
|
|
40985
|
+
// detect if scrollbar is available
|
|
40986
|
+
if (this.composerRef.el &&
|
|
40987
|
+
this.composerRef.el.scrollHeight > this.composerRef.el.clientHeight) {
|
|
40988
|
+
event.stopPropagation();
|
|
40989
|
+
}
|
|
40990
|
+
}
|
|
40841
40991
|
// ---------------------------------------------------------------------------
|
|
40842
40992
|
// Private
|
|
40843
40993
|
// ---------------------------------------------------------------------------
|
|
@@ -46314,8 +46464,8 @@ function compareDimensionValues(dimension, a, b) {
|
|
|
46314
46464
|
|
|
46315
46465
|
const NULL_SYMBOL = Symbol("NULL");
|
|
46316
46466
|
function createDate(dimension, value, locale) {
|
|
46317
|
-
const granularity = dimension.granularity;
|
|
46318
|
-
if (!
|
|
46467
|
+
const granularity = dimension.granularity || "month";
|
|
46468
|
+
if (!(granularity in MAP_VALUE_DIMENSION_DATE)) {
|
|
46319
46469
|
throw new Error(`Unknown date granularity: ${granularity}`);
|
|
46320
46470
|
}
|
|
46321
46471
|
const keyInMap = typeof value === "number" || typeof value === "string" ? value : NULL_SYMBOL;
|
|
@@ -46334,6 +46484,9 @@ function createDate(dimension, value, locale) {
|
|
|
46334
46484
|
case "month_number":
|
|
46335
46485
|
number = date.getMonth() + 1;
|
|
46336
46486
|
break;
|
|
46487
|
+
case "month":
|
|
46488
|
+
number = Math.floor(toNumber(value, locale));
|
|
46489
|
+
break;
|
|
46337
46490
|
case "iso_week_number":
|
|
46338
46491
|
number = date.getIsoWeek();
|
|
46339
46492
|
break;
|
|
@@ -46427,6 +46580,10 @@ const MAP_VALUE_DIMENSION_DATE = {
|
|
|
46427
46580
|
set: new Set(),
|
|
46428
46581
|
values: {},
|
|
46429
46582
|
},
|
|
46583
|
+
month: {
|
|
46584
|
+
set: new Set(),
|
|
46585
|
+
values: {},
|
|
46586
|
+
},
|
|
46430
46587
|
iso_week_number: {
|
|
46431
46588
|
set: new Set(),
|
|
46432
46589
|
values: {},
|
|
@@ -46637,7 +46794,7 @@ class SpreadsheetPivot {
|
|
|
46637
46794
|
const cells = this.filterDataEntriesFromDomain(this.dataEntries, domain);
|
|
46638
46795
|
const finalCell = cells[0]?.[dimension.nameWithGranularity];
|
|
46639
46796
|
if (dimension.type === "datetime") {
|
|
46640
|
-
const adapter = pivotTimeAdapter(dimension.granularity);
|
|
46797
|
+
const adapter = pivotTimeAdapter((dimension.granularity || "month"));
|
|
46641
46798
|
return adapter.toValueAndFormat(lastNode.value, this.getters.getLocale());
|
|
46642
46799
|
}
|
|
46643
46800
|
if (!finalCell) {
|
|
@@ -46755,7 +46912,7 @@ class SpreadsheetPivot {
|
|
|
46755
46912
|
if (nonEmptyCells.length === 0) {
|
|
46756
46913
|
return "integer";
|
|
46757
46914
|
}
|
|
46758
|
-
if (nonEmptyCells.every((cell) => cell.format && isDateTimeFormat(cell.format))) {
|
|
46915
|
+
if (nonEmptyCells.every((cell) => cell.type === CellValueType.number && cell.format && isDateTimeFormat(cell.format))) {
|
|
46759
46916
|
return "datetime";
|
|
46760
46917
|
}
|
|
46761
46918
|
if (nonEmptyCells.every((cell) => cell.type === CellValueType.boolean)) {
|
|
@@ -46834,7 +46991,12 @@ class SpreadsheetPivot {
|
|
|
46834
46991
|
entry[field.name] = { value: null, type: CellValueType.empty, formattedValue: "" };
|
|
46835
46992
|
}
|
|
46836
46993
|
else {
|
|
46837
|
-
|
|
46994
|
+
if (field.type === "char") {
|
|
46995
|
+
entry[field.name] = { ...cell, value: cell.formattedValue || null };
|
|
46996
|
+
}
|
|
46997
|
+
else {
|
|
46998
|
+
entry[field.name] = cell;
|
|
46999
|
+
}
|
|
46838
47000
|
}
|
|
46839
47001
|
}
|
|
46840
47002
|
entry["__count"] = { value: 1, type: CellValueType.number, formattedValue: "1" };
|
|
@@ -46848,7 +47010,7 @@ class SpreadsheetPivot {
|
|
|
46848
47010
|
for (const entry of dataEntries) {
|
|
46849
47011
|
for (const dimension of dateDimensions) {
|
|
46850
47012
|
const value = createDate(dimension, entry[dimension.fieldName]?.value || null, this.getters.getLocale());
|
|
46851
|
-
const adapter = pivotTimeAdapter(dimension.granularity);
|
|
47013
|
+
const adapter = pivotTimeAdapter((dimension.granularity || "month"));
|
|
46852
47014
|
const { format, value: valueToFormat } = adapter.toValueAndFormat(value, locale);
|
|
46853
47015
|
entry[dimension.nameWithGranularity] = {
|
|
46854
47016
|
value,
|
|
@@ -46868,6 +47030,7 @@ const dateGranularities = [
|
|
|
46868
47030
|
"year",
|
|
46869
47031
|
"quarter_number",
|
|
46870
47032
|
"month_number",
|
|
47033
|
+
"month",
|
|
46871
47034
|
"iso_week_number",
|
|
46872
47035
|
"day_of_month",
|
|
46873
47036
|
"day",
|
|
@@ -47118,7 +47281,7 @@ class PivotSidePanelStore extends SpreadsheetStore {
|
|
|
47118
47281
|
: this.datetimeGranularities);
|
|
47119
47282
|
}
|
|
47120
47283
|
for (const field of dateFields) {
|
|
47121
|
-
granularitiesPerFields[field.fieldName].delete(field.granularity);
|
|
47284
|
+
granularitiesPerFields[field.fieldName].delete(field.granularity || "month");
|
|
47122
47285
|
}
|
|
47123
47286
|
return granularitiesPerFields;
|
|
47124
47287
|
}
|
|
@@ -49288,6 +49451,8 @@ class GridComposer extends Component {
|
|
|
49288
49451
|
}
|
|
49289
49452
|
get composerProps() {
|
|
49290
49453
|
const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
|
|
49454
|
+
// Remove the wrapper border width
|
|
49455
|
+
const maxHeight = this.props.gridDims.height - this.rect.y - 2 * COMPOSER_BORDER_WIDTH;
|
|
49291
49456
|
return {
|
|
49292
49457
|
rect: { ...this.rect },
|
|
49293
49458
|
delimitation: {
|
|
@@ -49305,6 +49470,7 @@ class GridComposer extends Component {
|
|
|
49305
49470
|
}),
|
|
49306
49471
|
onInputContextMenu: this.props.onInputContextMenu,
|
|
49307
49472
|
composerStore: this.composerStore,
|
|
49473
|
+
inputStyle: `max-height: ${maxHeight}px;`,
|
|
49308
49474
|
};
|
|
49309
49475
|
}
|
|
49310
49476
|
get containerStyle() {
|
|
@@ -51968,10 +52134,6 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
51968
52134
|
ctx.scale(dpr, dpr);
|
|
51969
52135
|
for (const layer of OrderedLayers()) {
|
|
51970
52136
|
model.drawLayer(renderingContext, layer);
|
|
51971
|
-
// @ts-ignore 'drawLayer' is not declated as a mutator because:
|
|
51972
|
-
// it does not mutate anything. Most importantly it's used
|
|
51973
|
-
// during rendering. Invoking a mutator during rendering would
|
|
51974
|
-
// trigger another rendering, ultimately resulting in an infinite loop.
|
|
51975
52137
|
rendererStore.drawLayer(renderingContext, layer);
|
|
51976
52138
|
}
|
|
51977
52139
|
}
|
|
@@ -52662,7 +52824,7 @@ class Grid extends Component {
|
|
|
52662
52824
|
this.cellPopovers = useStore(CellPopoverStore);
|
|
52663
52825
|
useEffect(() => {
|
|
52664
52826
|
if (!this.sidePanel.isOpen) {
|
|
52665
|
-
this.DOMFocusableElementStore.
|
|
52827
|
+
this.DOMFocusableElementStore.focus();
|
|
52666
52828
|
}
|
|
52667
52829
|
}, () => [this.sidePanel.isOpen]);
|
|
52668
52830
|
useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
|
|
@@ -52872,7 +53034,7 @@ class Grid extends Component {
|
|
|
52872
53034
|
focusDefaultElement() {
|
|
52873
53035
|
if (!this.env.model.getters.getSelectedFigureId() &&
|
|
52874
53036
|
this.composerFocusStore.activeComposer.editionMode === "inactive") {
|
|
52875
|
-
this.DOMFocusableElementStore.
|
|
53037
|
+
this.DOMFocusableElementStore.focus();
|
|
52876
53038
|
}
|
|
52877
53039
|
}
|
|
52878
53040
|
get gridEl() {
|
|
@@ -53217,6 +53379,322 @@ class Grid extends Component {
|
|
|
53217
53379
|
}
|
|
53218
53380
|
}
|
|
53219
53381
|
|
|
53382
|
+
css /* scss */ `
|
|
53383
|
+
.o_pivot_html_renderer {
|
|
53384
|
+
width: 100%;
|
|
53385
|
+
border-collapse: collapse;
|
|
53386
|
+
|
|
53387
|
+
&:hover {
|
|
53388
|
+
cursor: pointer;
|
|
53389
|
+
}
|
|
53390
|
+
|
|
53391
|
+
td,
|
|
53392
|
+
th {
|
|
53393
|
+
border: 1px solid #dee2e6;
|
|
53394
|
+
background-color: #fff;
|
|
53395
|
+
padding: 0.3rem;
|
|
53396
|
+
white-space: nowrap;
|
|
53397
|
+
|
|
53398
|
+
&:hover {
|
|
53399
|
+
filter: brightness(0.9);
|
|
53400
|
+
}
|
|
53401
|
+
}
|
|
53402
|
+
|
|
53403
|
+
td {
|
|
53404
|
+
text-align: right;
|
|
53405
|
+
}
|
|
53406
|
+
|
|
53407
|
+
th {
|
|
53408
|
+
background-color: #f5f5f5;
|
|
53409
|
+
font-weight: bold;
|
|
53410
|
+
color: black;
|
|
53411
|
+
}
|
|
53412
|
+
|
|
53413
|
+
.o_missing_value {
|
|
53414
|
+
color: #46646d;
|
|
53415
|
+
background: #e7f2f6;
|
|
53416
|
+
}
|
|
53417
|
+
}
|
|
53418
|
+
`;
|
|
53419
|
+
class PivotHTMLRenderer extends Component {
|
|
53420
|
+
static template = "o_spreadsheet.PivotHTMLRenderer";
|
|
53421
|
+
static components = { Checkbox };
|
|
53422
|
+
static props = {
|
|
53423
|
+
pivotId: String,
|
|
53424
|
+
onCellClicked: Function,
|
|
53425
|
+
};
|
|
53426
|
+
pivot = this.env.model.getters.getPivot(this.props.pivotId);
|
|
53427
|
+
data = {
|
|
53428
|
+
columns: [],
|
|
53429
|
+
rows: [],
|
|
53430
|
+
values: [],
|
|
53431
|
+
};
|
|
53432
|
+
state = useState({
|
|
53433
|
+
showMissingValuesOnly: false,
|
|
53434
|
+
});
|
|
53435
|
+
setup() {
|
|
53436
|
+
const table = this.pivot.getTableStructure();
|
|
53437
|
+
const formulaId = this.env.model.getters.getPivotFormulaId(this.props.pivotId);
|
|
53438
|
+
this.data = {
|
|
53439
|
+
columns: this._buildColHeaders(formulaId, table),
|
|
53440
|
+
rows: this._buildRowHeaders(formulaId, table),
|
|
53441
|
+
values: this._buildValues(formulaId, table),
|
|
53442
|
+
};
|
|
53443
|
+
}
|
|
53444
|
+
get tracker() {
|
|
53445
|
+
return this.env.model.getters.getPivotPresenceTracker(this.props.pivotId);
|
|
53446
|
+
}
|
|
53447
|
+
// ---------------------------------------------------------------------
|
|
53448
|
+
// Missing values building
|
|
53449
|
+
// ---------------------------------------------------------------------
|
|
53450
|
+
/**
|
|
53451
|
+
* Retrieve the data to display in the Pivot Table
|
|
53452
|
+
* In the case when showMissingValuesOnly is false, the returned value
|
|
53453
|
+
* is the complete data
|
|
53454
|
+
* In the case when showMissingValuesOnly is true, the returned value is
|
|
53455
|
+
* the data which contains only missing values in the rows and cols. In
|
|
53456
|
+
* the rows, we also return the parent rows of rows which contains missing
|
|
53457
|
+
* values, to give context to the user.
|
|
53458
|
+
*
|
|
53459
|
+
*/
|
|
53460
|
+
getTableData() {
|
|
53461
|
+
if (!this.state.showMissingValuesOnly) {
|
|
53462
|
+
return this.data;
|
|
53463
|
+
}
|
|
53464
|
+
const colIndexes = this.getColumnsIndexes();
|
|
53465
|
+
const rowIndexes = this.getRowsIndexes();
|
|
53466
|
+
const columns = this.buildColumnsMissing(colIndexes);
|
|
53467
|
+
const rows = this.buildRowsMissing(rowIndexes);
|
|
53468
|
+
const values = this.buildValuesMissing(colIndexes, rowIndexes);
|
|
53469
|
+
return { columns, rows, values };
|
|
53470
|
+
}
|
|
53471
|
+
/**
|
|
53472
|
+
* Retrieve the parents of the given row
|
|
53473
|
+
* ex:
|
|
53474
|
+
* Australia
|
|
53475
|
+
* January
|
|
53476
|
+
* February
|
|
53477
|
+
* The parent of "January" is "Australia"
|
|
53478
|
+
*/
|
|
53479
|
+
addRecursiveRow(index) {
|
|
53480
|
+
const rows = this.pivot.getTableStructure().rows;
|
|
53481
|
+
const row = [...rows[index].values];
|
|
53482
|
+
if (row.length <= 1) {
|
|
53483
|
+
return [index];
|
|
53484
|
+
}
|
|
53485
|
+
row.pop();
|
|
53486
|
+
const parentRowIndex = rows.findIndex((r) => JSON.stringify(r.values) === JSON.stringify(row));
|
|
53487
|
+
return [index].concat(this.addRecursiveRow(parentRowIndex));
|
|
53488
|
+
}
|
|
53489
|
+
/**
|
|
53490
|
+
* Create the columns to be used, based on the indexes of the columns in
|
|
53491
|
+
* which a missing value is present
|
|
53492
|
+
*
|
|
53493
|
+
*/
|
|
53494
|
+
buildColumnsMissing(indexes) {
|
|
53495
|
+
// columnsMap explode the columns in an array of array of the same
|
|
53496
|
+
// size with the index of each column, repeated 'span' times.
|
|
53497
|
+
// ex:
|
|
53498
|
+
// | A | B |
|
|
53499
|
+
// | 1 | 2 | 3 |
|
|
53500
|
+
// => [
|
|
53501
|
+
// [0, 0, 1]
|
|
53502
|
+
// [0, 1, 2]
|
|
53503
|
+
// ]
|
|
53504
|
+
const columnsMap = [];
|
|
53505
|
+
for (const column of this.data.columns) {
|
|
53506
|
+
const columnMap = [];
|
|
53507
|
+
for (const index in column) {
|
|
53508
|
+
for (let i = 0; i < column[index].span; i++) {
|
|
53509
|
+
columnMap.push(parseInt(index, 10));
|
|
53510
|
+
}
|
|
53511
|
+
}
|
|
53512
|
+
columnsMap.push(columnMap);
|
|
53513
|
+
}
|
|
53514
|
+
// Remove the columns that are not present in indexes
|
|
53515
|
+
for (let i = columnsMap[columnsMap.length - 1].length; i >= 0; i--) {
|
|
53516
|
+
if (!indexes.includes(i)) {
|
|
53517
|
+
for (const columnMap of columnsMap) {
|
|
53518
|
+
columnMap.splice(i, 1);
|
|
53519
|
+
}
|
|
53520
|
+
}
|
|
53521
|
+
}
|
|
53522
|
+
// Build the columns
|
|
53523
|
+
const columns = [];
|
|
53524
|
+
for (const mapIndex in columnsMap) {
|
|
53525
|
+
const column = [];
|
|
53526
|
+
let index = undefined;
|
|
53527
|
+
let span = 1;
|
|
53528
|
+
for (let i = 0; i < columnsMap[mapIndex].length; i++) {
|
|
53529
|
+
if (index !== columnsMap[mapIndex][i]) {
|
|
53530
|
+
if (index !== undefined) {
|
|
53531
|
+
column.push(Object.assign({}, this.data.columns[mapIndex][index], { span }));
|
|
53532
|
+
}
|
|
53533
|
+
index = columnsMap[mapIndex][i];
|
|
53534
|
+
span = 1;
|
|
53535
|
+
}
|
|
53536
|
+
else {
|
|
53537
|
+
span++;
|
|
53538
|
+
}
|
|
53539
|
+
}
|
|
53540
|
+
if (index !== undefined) {
|
|
53541
|
+
column.push(Object.assign({}, this.data.columns[mapIndex][index], { span }));
|
|
53542
|
+
}
|
|
53543
|
+
columns.push(column);
|
|
53544
|
+
}
|
|
53545
|
+
return columns;
|
|
53546
|
+
}
|
|
53547
|
+
/**
|
|
53548
|
+
* Create the rows to be used, based on the indexes of the rows in
|
|
53549
|
+
* which a missing value is present.
|
|
53550
|
+
*/
|
|
53551
|
+
buildRowsMissing(indexes) {
|
|
53552
|
+
return indexes.map((index) => this.data.rows[index]);
|
|
53553
|
+
}
|
|
53554
|
+
/**
|
|
53555
|
+
* Create the value to be used, based on the indexes of the columns and
|
|
53556
|
+
* rows in which a missing value is present.
|
|
53557
|
+
*/
|
|
53558
|
+
buildValuesMissing(colIndexes, rowIndexes) {
|
|
53559
|
+
const values = colIndexes.map(() => []);
|
|
53560
|
+
for (const row of rowIndexes) {
|
|
53561
|
+
for (const col in colIndexes) {
|
|
53562
|
+
values[col].push(this.data.values[colIndexes[col]][row]);
|
|
53563
|
+
}
|
|
53564
|
+
}
|
|
53565
|
+
return values;
|
|
53566
|
+
}
|
|
53567
|
+
getColumnsIndexes() {
|
|
53568
|
+
const indexes = new Set();
|
|
53569
|
+
for (let i = 0; i < this.data.columns.length; i++) {
|
|
53570
|
+
const exploded = [];
|
|
53571
|
+
for (let y = 0; y < this.data.columns[i].length; y++) {
|
|
53572
|
+
for (let x = 0; x < this.data.columns[i][y].span; x++) {
|
|
53573
|
+
exploded.push(this.data.columns[i][y]);
|
|
53574
|
+
}
|
|
53575
|
+
}
|
|
53576
|
+
for (let y = 0; y < exploded.length; y++) {
|
|
53577
|
+
if (exploded[y].isMissing) {
|
|
53578
|
+
indexes.add(y);
|
|
53579
|
+
}
|
|
53580
|
+
}
|
|
53581
|
+
}
|
|
53582
|
+
for (let i = 0; i < this.data.columns[this.data.columns.length - 1].length; i++) {
|
|
53583
|
+
const values = this.data.values[i];
|
|
53584
|
+
if (values.find((x) => x.isMissing)) {
|
|
53585
|
+
indexes.add(i);
|
|
53586
|
+
}
|
|
53587
|
+
}
|
|
53588
|
+
return Array.from(indexes).sort((a, b) => a - b);
|
|
53589
|
+
}
|
|
53590
|
+
getRowsIndexes() {
|
|
53591
|
+
const rowIndexes = new Set();
|
|
53592
|
+
for (let i = 0; i < this.data.rows.length; i++) {
|
|
53593
|
+
if (this.data.rows[i].isMissing) {
|
|
53594
|
+
rowIndexes.add(i);
|
|
53595
|
+
}
|
|
53596
|
+
for (const col of this.data.values) {
|
|
53597
|
+
if (col[i].isMissing) {
|
|
53598
|
+
this.addRecursiveRow(i).forEach((x) => rowIndexes.add(x));
|
|
53599
|
+
}
|
|
53600
|
+
}
|
|
53601
|
+
}
|
|
53602
|
+
return Array.from(rowIndexes).sort((a, b) => a - b);
|
|
53603
|
+
}
|
|
53604
|
+
// ---------------------------------------------------------------------
|
|
53605
|
+
// Data table creation
|
|
53606
|
+
// ---------------------------------------------------------------------
|
|
53607
|
+
_buildColHeaders(id, table) {
|
|
53608
|
+
const headers = [];
|
|
53609
|
+
for (const row of table.columns) {
|
|
53610
|
+
const current = [];
|
|
53611
|
+
for (const cell of row) {
|
|
53612
|
+
const args = [];
|
|
53613
|
+
for (let i = 0; i < cell.fields.length; i++) {
|
|
53614
|
+
args.push({ value: cell.fields[i] }, { value: cell.values[i] });
|
|
53615
|
+
}
|
|
53616
|
+
const domain = this.pivot.parseArgsToPivotDomain(args);
|
|
53617
|
+
const locale = this.env.model.getters.getLocale();
|
|
53618
|
+
if (domain.at(-1)?.field === "measure") {
|
|
53619
|
+
const { value, format } = this.pivot.getPivotMeasureValue(toString(domain.at(-1).value), domain);
|
|
53620
|
+
current.push({
|
|
53621
|
+
formula: `=PIVOT.HEADER(${generatePivotArgs(id, domain).join(",")})`,
|
|
53622
|
+
value: formatValue(value, { format, locale }),
|
|
53623
|
+
span: cell.width,
|
|
53624
|
+
isMissing: !this.tracker?.isHeaderPresent(domain),
|
|
53625
|
+
});
|
|
53626
|
+
}
|
|
53627
|
+
else {
|
|
53628
|
+
const { value, format } = this.pivot.getPivotHeaderValueAndFormat(domain);
|
|
53629
|
+
current.push({
|
|
53630
|
+
formula: `=PIVOT.HEADER(${generatePivotArgs(id, domain).join(",")})`,
|
|
53631
|
+
value: formatValue(value, { format, locale }),
|
|
53632
|
+
span: cell.width,
|
|
53633
|
+
isMissing: !this.tracker?.isHeaderPresent(domain),
|
|
53634
|
+
});
|
|
53635
|
+
}
|
|
53636
|
+
}
|
|
53637
|
+
headers.push(current);
|
|
53638
|
+
}
|
|
53639
|
+
const last = headers[headers.length - 1];
|
|
53640
|
+
headers[headers.length - 1] = last.map((cell) => {
|
|
53641
|
+
if (!cell.isMissing) {
|
|
53642
|
+
cell.style = "color: #756f6f;";
|
|
53643
|
+
}
|
|
53644
|
+
return cell;
|
|
53645
|
+
});
|
|
53646
|
+
return headers;
|
|
53647
|
+
}
|
|
53648
|
+
_buildRowHeaders(id, table) {
|
|
53649
|
+
const headers = [];
|
|
53650
|
+
for (const row of table.rows) {
|
|
53651
|
+
const args = [];
|
|
53652
|
+
for (let i = 0; i < row.fields.length; i++) {
|
|
53653
|
+
args.push({ value: row.fields[i] }, { value: row.values[i] });
|
|
53654
|
+
}
|
|
53655
|
+
const domain = this.pivot.parseArgsToPivotDomain(args);
|
|
53656
|
+
const { value, format } = this.pivot.getPivotHeaderValueAndFormat(domain);
|
|
53657
|
+
const locale = this.env.model.getters.getLocale();
|
|
53658
|
+
const cell = {
|
|
53659
|
+
formula: `=PIVOT.HEADER(${generatePivotArgs(id, domain).join(",")})`,
|
|
53660
|
+
value: formatValue(value, { format, locale }),
|
|
53661
|
+
isMissing: !this.tracker?.isHeaderPresent(domain),
|
|
53662
|
+
};
|
|
53663
|
+
if (row.indent > 1) {
|
|
53664
|
+
cell.style = `padding-left: ${row.indent - 1 * 10}px`;
|
|
53665
|
+
}
|
|
53666
|
+
headers.push(cell);
|
|
53667
|
+
}
|
|
53668
|
+
return headers;
|
|
53669
|
+
}
|
|
53670
|
+
_buildValues(id, table) {
|
|
53671
|
+
const values = [];
|
|
53672
|
+
for (const col of table.columns.at(-1) || []) {
|
|
53673
|
+
const current = [];
|
|
53674
|
+
const measure = toString(col.values[col.values.length - 1]);
|
|
53675
|
+
for (const row of table.rows) {
|
|
53676
|
+
const args = [];
|
|
53677
|
+
for (let i = 0; i < row.fields.length; i++) {
|
|
53678
|
+
args.push({ value: row.fields[i] }, { value: row.values[i] });
|
|
53679
|
+
}
|
|
53680
|
+
for (let i = 0; i < col.fields.length - 1; i++) {
|
|
53681
|
+
args.push({ value: col.fields[i] }, { value: col.values[i] });
|
|
53682
|
+
}
|
|
53683
|
+
const domain = this.pivot.parseArgsToPivotDomain(args);
|
|
53684
|
+
const { value, format } = this.pivot.getPivotCellValueAndFormat(measure, domain);
|
|
53685
|
+
const locale = this.env.model.getters.getLocale();
|
|
53686
|
+
current.push({
|
|
53687
|
+
formula: `=PIVOT.VALUE(${generatePivotArgs(id, domain, measure).join(",")})`,
|
|
53688
|
+
value: formatValue(value, { format, locale }),
|
|
53689
|
+
isMissing: !this.tracker?.isValuePresent(measure, domain),
|
|
53690
|
+
});
|
|
53691
|
+
}
|
|
53692
|
+
values.push(current);
|
|
53693
|
+
}
|
|
53694
|
+
return values;
|
|
53695
|
+
}
|
|
53696
|
+
}
|
|
53697
|
+
|
|
53220
53698
|
/**
|
|
53221
53699
|
* BasePlugin
|
|
53222
53700
|
*
|
|
@@ -54567,7 +55045,7 @@ class ChartPlugin extends CorePlugin {
|
|
|
54567
55045
|
case "CREATE_CHART":
|
|
54568
55046
|
return this.checkValidations(cmd, this.chainValidations(this.validateChartDefinition, this.checkChartDuplicate));
|
|
54569
55047
|
case "UPDATE_CHART":
|
|
54570
|
-
return this.checkValidations(cmd, this.chainValidations(this.validateChartDefinition, this.checkChartExists));
|
|
55048
|
+
return this.checkValidations(cmd, this.chainValidations(this.validateChartDefinition, this.checkChartExists, this.checkChartChanged));
|
|
54571
55049
|
default:
|
|
54572
55050
|
return "Success" /* CommandResult.Success */;
|
|
54573
55051
|
}
|
|
@@ -54722,9 +55200,12 @@ class ChartPlugin extends CorePlugin {
|
|
|
54722
55200
|
: "Success" /* CommandResult.Success */;
|
|
54723
55201
|
}
|
|
54724
55202
|
checkChartExists(cmd) {
|
|
54725
|
-
return this.
|
|
54726
|
-
|
|
54727
|
-
|
|
55203
|
+
return this.isChartDefined(cmd.id) ? "Success" /* CommandResult.Success */ : "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
|
|
55204
|
+
}
|
|
55205
|
+
checkChartChanged(cmd) {
|
|
55206
|
+
return deepEquals(this.getChartDefinition(cmd.id), cmd.definition)
|
|
55207
|
+
? "NoChanges" /* CommandResult.NoChanges */
|
|
55208
|
+
: "Success" /* CommandResult.Success */;
|
|
54728
55209
|
}
|
|
54729
55210
|
}
|
|
54730
55211
|
|
|
@@ -56673,7 +57154,7 @@ class RangeAdapter {
|
|
|
56673
57154
|
if (range.sheetId === cmd.sheetId) {
|
|
56674
57155
|
return { changeType: "CHANGE", range };
|
|
56675
57156
|
}
|
|
56676
|
-
if (
|
|
57157
|
+
if (isSheetNameEqual(range.invalidSheetName, cmd.name)) {
|
|
56677
57158
|
const invalidSheetName = undefined;
|
|
56678
57159
|
const sheetId = cmd.sheetId;
|
|
56679
57160
|
const newRange = range.clone({ sheetId, invalidSheetName });
|
|
@@ -57043,6 +57524,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
57043
57524
|
"getCommandZones",
|
|
57044
57525
|
"getUnboundedZone",
|
|
57045
57526
|
"checkElementsIncludeAllNonFrozenHeaders",
|
|
57527
|
+
"getDuplicateSheetName",
|
|
57046
57528
|
];
|
|
57047
57529
|
sheetIdsMapName = {};
|
|
57048
57530
|
orderedSheetIds = [];
|
|
@@ -57067,7 +57549,11 @@ class SheetPlugin extends CorePlugin {
|
|
|
57067
57549
|
return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
|
|
57068
57550
|
}
|
|
57069
57551
|
case "DUPLICATE_SHEET": {
|
|
57070
|
-
|
|
57552
|
+
if (this.sheets[cmd.sheetIdTo])
|
|
57553
|
+
return "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */;
|
|
57554
|
+
if (this.orderedSheetIds.map(this.getSheetName.bind(this)).includes(cmd.sheetNameTo))
|
|
57555
|
+
return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
|
|
57556
|
+
return "Success" /* CommandResult.Success */;
|
|
57071
57557
|
}
|
|
57072
57558
|
case "MOVE_SHEET":
|
|
57073
57559
|
try {
|
|
@@ -57144,7 +57630,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
57144
57630
|
this.showSheet(cmd.sheetId);
|
|
57145
57631
|
break;
|
|
57146
57632
|
case "DUPLICATE_SHEET":
|
|
57147
|
-
this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo);
|
|
57633
|
+
this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo, cmd.sheetNameTo);
|
|
57148
57634
|
break;
|
|
57149
57635
|
case "DELETE_SHEET":
|
|
57150
57636
|
this.deleteSheet(this.sheets[cmd.sheetId]);
|
|
@@ -57285,7 +57771,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
57285
57771
|
if (name) {
|
|
57286
57772
|
const unquotedName = getUnquotedSheetName(name);
|
|
57287
57773
|
for (const key in this.sheetIdsMapName) {
|
|
57288
|
-
if (key
|
|
57774
|
+
if (isSheetNameEqual(key, unquotedName)) {
|
|
57289
57775
|
return this.sheetIdsMapName[key];
|
|
57290
57776
|
}
|
|
57291
57777
|
}
|
|
@@ -57351,10 +57837,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
57351
57837
|
}
|
|
57352
57838
|
getNextSheetName(baseName = "Sheet") {
|
|
57353
57839
|
const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
|
|
57354
|
-
return
|
|
57355
|
-
compute: (name, i) => `${name}${i}`,
|
|
57356
|
-
computeFirstOne: true,
|
|
57357
|
-
});
|
|
57840
|
+
return getNextSheetName(names, baseName);
|
|
57358
57841
|
}
|
|
57359
57842
|
getSheetSize(sheetId) {
|
|
57360
57843
|
return {
|
|
@@ -57536,7 +58019,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
57536
58019
|
}
|
|
57537
58020
|
const { orderedSheetIds, sheets } = this;
|
|
57538
58021
|
const name = cmd.name && cmd.name.trim().toLowerCase();
|
|
57539
|
-
if (orderedSheetIds.find((id) => sheets[id]?.name
|
|
58022
|
+
if (orderedSheetIds.find((id) => isSheetNameEqual(sheets[id]?.name, name) && id !== cmd.sheetId)) {
|
|
57540
58023
|
return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
|
|
57541
58024
|
}
|
|
57542
58025
|
if (FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX.test(name)) {
|
|
@@ -57600,9 +58083,8 @@ class SheetPlugin extends CorePlugin {
|
|
|
57600
58083
|
showSheet(sheetId) {
|
|
57601
58084
|
this.history.update("sheets", sheetId, "isVisible", true);
|
|
57602
58085
|
}
|
|
57603
|
-
duplicateSheet(fromId, toId) {
|
|
58086
|
+
duplicateSheet(fromId, toId, toName) {
|
|
57604
58087
|
const sheet = this.getSheet(fromId);
|
|
57605
|
-
const toName = this.getDuplicateSheetName(sheet.name);
|
|
57606
58088
|
const newSheet = deepCopy(sheet);
|
|
57607
58089
|
newSheet.id = toId;
|
|
57608
58090
|
newSheet.name = toName;
|
|
@@ -57635,8 +58117,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
57635
58117
|
}
|
|
57636
58118
|
getDuplicateSheetName(sheetName) {
|
|
57637
58119
|
const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
|
|
57638
|
-
|
|
57639
|
-
return getUniqueText(baseName.toString(), names);
|
|
58120
|
+
return getDuplicateSheetName(sheetName, names);
|
|
57640
58121
|
}
|
|
57641
58122
|
deleteSheet(sheet) {
|
|
57642
58123
|
const name = sheet.name;
|
|
@@ -60431,8 +60912,8 @@ class SpreadingRelation {
|
|
|
60431
60912
|
const EMPTY_ARRAY = [];
|
|
60432
60913
|
|
|
60433
60914
|
const MAX_ITERATION = 30;
|
|
60434
|
-
const ERROR_CYCLE_CELL = createEvaluatedCell(new CircularDependencyError());
|
|
60435
|
-
const EMPTY_CELL = createEvaluatedCell({ value: null });
|
|
60915
|
+
const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell(new CircularDependencyError()));
|
|
60916
|
+
const EMPTY_CELL = Object.freeze(createEvaluatedCell({ value: null }));
|
|
60436
60917
|
class Evaluator {
|
|
60437
60918
|
context;
|
|
60438
60919
|
getters;
|
|
@@ -66431,6 +66912,55 @@ class HistoryPlugin extends UIPlugin {
|
|
|
66431
66912
|
}
|
|
66432
66913
|
}
|
|
66433
66914
|
|
|
66915
|
+
class PivotPresenceTracker {
|
|
66916
|
+
trackedValues = new Set();
|
|
66917
|
+
domainToArray(domain) {
|
|
66918
|
+
return domain.flatMap((node) => [node.field, toString(node.value)]);
|
|
66919
|
+
}
|
|
66920
|
+
isValuePresent(measure, domain) {
|
|
66921
|
+
const key = JSON.stringify({ measure, domain: this.domainToArray(domain) });
|
|
66922
|
+
return this.trackedValues.has(key);
|
|
66923
|
+
}
|
|
66924
|
+
isHeaderPresent(domain) {
|
|
66925
|
+
const key = JSON.stringify({ domain: this.domainToArray(domain) });
|
|
66926
|
+
return this.trackedValues.has(key);
|
|
66927
|
+
}
|
|
66928
|
+
trackValue(measure, domain) {
|
|
66929
|
+
const key = JSON.stringify({ measure, domain: this.domainToArray(domain) });
|
|
66930
|
+
this.trackedValues.add(key);
|
|
66931
|
+
}
|
|
66932
|
+
trackHeader(domain) {
|
|
66933
|
+
const key = JSON.stringify({ domain: this.domainToArray(domain) });
|
|
66934
|
+
this.trackedValues.add(key);
|
|
66935
|
+
}
|
|
66936
|
+
}
|
|
66937
|
+
|
|
66938
|
+
class PivotPresencePlugin extends UIPlugin {
|
|
66939
|
+
static getters = ["getPivotPresenceTracker"];
|
|
66940
|
+
trackPresencePivotId;
|
|
66941
|
+
tracker;
|
|
66942
|
+
handle(cmd) {
|
|
66943
|
+
switch (cmd.type) {
|
|
66944
|
+
case "PIVOT_START_PRESENCE_TRACKING":
|
|
66945
|
+
this.tracker = new PivotPresenceTracker();
|
|
66946
|
+
this.trackPresencePivotId = cmd.pivotId;
|
|
66947
|
+
break;
|
|
66948
|
+
case "PIVOT_STOP_PRESENCE_TRACKING":
|
|
66949
|
+
this.trackPresencePivotId = undefined;
|
|
66950
|
+
break;
|
|
66951
|
+
}
|
|
66952
|
+
}
|
|
66953
|
+
getPivotPresenceTracker(pivotId) {
|
|
66954
|
+
if (this.trackPresencePivotId !== pivotId) {
|
|
66955
|
+
return undefined;
|
|
66956
|
+
}
|
|
66957
|
+
if (!this.tracker) {
|
|
66958
|
+
throw new Error("Tracker not initialized");
|
|
66959
|
+
}
|
|
66960
|
+
return this.tracker;
|
|
66961
|
+
}
|
|
66962
|
+
}
|
|
66963
|
+
|
|
66434
66964
|
class SplitToColumnsPlugin extends UIPlugin {
|
|
66435
66965
|
static getters = ["getAutomaticSeparator"];
|
|
66436
66966
|
allowDispatch(cmd) {
|
|
@@ -69181,6 +69711,7 @@ const featurePluginRegistry = new Registry()
|
|
|
69181
69711
|
.add("automatic_sum", AutomaticSumPlugin)
|
|
69182
69712
|
.add("format", FormatPlugin)
|
|
69183
69713
|
.add("insert_pivot", InsertPivotPlugin)
|
|
69714
|
+
.add("pivot_presence", PivotPresencePlugin)
|
|
69184
69715
|
.add("split_to_columns", SplitToColumnsPlugin)
|
|
69185
69716
|
.add("collaborative", CollaborativePlugin)
|
|
69186
69717
|
.add("history", HistoryPlugin)
|
|
@@ -69561,11 +70092,11 @@ class BottomBarSheet extends Component {
|
|
|
69561
70092
|
if (ev.key === "Enter") {
|
|
69562
70093
|
ev.preventDefault();
|
|
69563
70094
|
this.stopEdition();
|
|
69564
|
-
this.DOMFocusableElementStore.
|
|
70095
|
+
this.DOMFocusableElementStore.focus();
|
|
69565
70096
|
}
|
|
69566
70097
|
if (ev.key === "Escape") {
|
|
69567
70098
|
this.cancelEdition();
|
|
69568
|
-
this.DOMFocusableElementStore.
|
|
70099
|
+
this.DOMFocusableElementStore.focus();
|
|
69569
70100
|
}
|
|
69570
70101
|
}
|
|
69571
70102
|
onMouseEventSheetName(ev) {
|
|
@@ -71737,11 +72268,13 @@ class Spreadsheet extends Component {
|
|
|
71737
72268
|
this.checkViewportSize();
|
|
71738
72269
|
stores.on("store-updated", this, render);
|
|
71739
72270
|
resizeObserver.observe(this.spreadsheetRef.el);
|
|
72271
|
+
registerChartJSExtensions();
|
|
71740
72272
|
});
|
|
71741
72273
|
onWillUnmount(() => {
|
|
71742
72274
|
this.unbindModelEvents();
|
|
71743
72275
|
stores.off("store-updated", this);
|
|
71744
72276
|
resizeObserver.disconnect();
|
|
72277
|
+
unregisterChartJsExtensions();
|
|
71745
72278
|
});
|
|
71746
72279
|
onPatched(() => {
|
|
71747
72280
|
this.checkViewportSize();
|
|
@@ -76174,6 +76707,7 @@ const components = {
|
|
|
76174
76707
|
PivotDimensionOrder,
|
|
76175
76708
|
PivotDimension,
|
|
76176
76709
|
PivotLayoutConfigurator,
|
|
76710
|
+
PivotHTMLRenderer,
|
|
76177
76711
|
PivotDeferUpdate,
|
|
76178
76712
|
PivotTitleSection,
|
|
76179
76713
|
CogWheelMenu,
|
|
@@ -76223,6 +76757,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
|
|
|
76223
76757
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
76224
76758
|
|
|
76225
76759
|
|
|
76226
|
-
__info__.version = "18.2.
|
|
76227
|
-
__info__.date = "2025-05-
|
|
76228
|
-
__info__.hash = "
|
|
76760
|
+
__info__.version = "18.2.12";
|
|
76761
|
+
__info__.date = "2025-05-13T17:52:23.989Z";
|
|
76762
|
+
__info__.hash = "ba2ba9b";
|