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