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