@odoo/o-spreadsheet 18.3.2 → 18.3.3
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 +526 -97
- package/dist/o-spreadsheet.d.ts +269 -160
- package/dist/o-spreadsheet.esm.js +526 -97
- package/dist/o-spreadsheet.iife.js +526 -97
- package/dist/o-spreadsheet.iife.min.js +414 -378
- package/dist/o_spreadsheet.xml +60 -13
- 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.3.
|
|
6
|
-
* @date 2025-05-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.3.3
|
|
6
|
+
* @date 2025-05-13T17:54:43.312Z
|
|
7
|
+
* @hash b79924a
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -3320,7 +3320,7 @@
|
|
|
3320
3320
|
*/
|
|
3321
3321
|
const getFormulaNumberRegex = memoize(function getFormulaNumberRegex(decimalSeparator) {
|
|
3322
3322
|
decimalSeparator = escapeRegExp(decimalSeparator);
|
|
3323
|
-
return new RegExp(`(?:^-?\\d+(?:${decimalSeparator}?\\d*(?:e
|
|
3323
|
+
return new RegExp(`(?:^-?\\d+(?:${decimalSeparator}?\\d*(?:e(\\+|-)?\\d+)?)?|^-?${decimalSeparator}\\d+)(?!\\w|!)`);
|
|
3324
3324
|
});
|
|
3325
3325
|
const getNumberRegex = memoize(function getNumberRegex(locale) {
|
|
3326
3326
|
const decimalSeparator = escapeRegExp(locale.decimalSeparator);
|
|
@@ -6001,6 +6001,67 @@
|
|
|
6001
6001
|
return MIN_DELAY + (MAX_DELAY - MIN_DELAY) * Math.exp(-ACCELERATION * (value - 1));
|
|
6002
6002
|
}
|
|
6003
6003
|
|
|
6004
|
+
function createDefaultRows(rowNumber) {
|
|
6005
|
+
const rows = [];
|
|
6006
|
+
for (let i = 0; i < rowNumber; i++) {
|
|
6007
|
+
const row = {
|
|
6008
|
+
cells: {},
|
|
6009
|
+
};
|
|
6010
|
+
rows.push(row);
|
|
6011
|
+
}
|
|
6012
|
+
return rows;
|
|
6013
|
+
}
|
|
6014
|
+
function moveHeaderIndexesOnHeaderAddition(indexHeaderAdded, numberAdded, headers) {
|
|
6015
|
+
return headers.map((header) => {
|
|
6016
|
+
if (header >= indexHeaderAdded) {
|
|
6017
|
+
return header + numberAdded;
|
|
6018
|
+
}
|
|
6019
|
+
return header;
|
|
6020
|
+
});
|
|
6021
|
+
}
|
|
6022
|
+
function moveHeaderIndexesOnHeaderDeletion(deletedHeaders, headers) {
|
|
6023
|
+
deletedHeaders = [...deletedHeaders].sort((a, b) => b - a);
|
|
6024
|
+
return headers
|
|
6025
|
+
.map((header) => {
|
|
6026
|
+
for (const deletedHeader of deletedHeaders) {
|
|
6027
|
+
if (header > deletedHeader) {
|
|
6028
|
+
header--;
|
|
6029
|
+
}
|
|
6030
|
+
else if (header === deletedHeader) {
|
|
6031
|
+
return undefined;
|
|
6032
|
+
}
|
|
6033
|
+
}
|
|
6034
|
+
return header;
|
|
6035
|
+
})
|
|
6036
|
+
.filter(isDefined);
|
|
6037
|
+
}
|
|
6038
|
+
function getNextSheetName(existingNames, baseName = "Sheet") {
|
|
6039
|
+
let i = 1;
|
|
6040
|
+
let name = `${baseName}${i}`;
|
|
6041
|
+
while (existingNames.includes(name)) {
|
|
6042
|
+
name = `${baseName}${i}`;
|
|
6043
|
+
i++;
|
|
6044
|
+
}
|
|
6045
|
+
return name;
|
|
6046
|
+
}
|
|
6047
|
+
function getDuplicateSheetName(nameToDuplicate, existingNames) {
|
|
6048
|
+
let i = 1;
|
|
6049
|
+
const baseName = _t("Copy of %s", nameToDuplicate);
|
|
6050
|
+
let name = baseName.toString();
|
|
6051
|
+
while (existingNames.includes(name)) {
|
|
6052
|
+
name = `${baseName} (${i})`;
|
|
6053
|
+
i++;
|
|
6054
|
+
}
|
|
6055
|
+
return name;
|
|
6056
|
+
}
|
|
6057
|
+
function isSheetNameEqual(name1, name2) {
|
|
6058
|
+
if (name1 === undefined || name2 === undefined) {
|
|
6059
|
+
return false;
|
|
6060
|
+
}
|
|
6061
|
+
return (getUnquotedSheetName(name1.trim().toUpperCase()) ===
|
|
6062
|
+
getUnquotedSheetName(name2.trim().toUpperCase()));
|
|
6063
|
+
}
|
|
6064
|
+
|
|
6004
6065
|
function createRange(args, getSheetSize) {
|
|
6005
6066
|
const unboundedZone = args.zone;
|
|
6006
6067
|
const zone = boundUnboundedZone(unboundedZone, getSheetSize(args.sheetId));
|
|
@@ -6291,7 +6352,7 @@
|
|
|
6291
6352
|
elements.sort((a, b) => b - a);
|
|
6292
6353
|
const groups = groupConsecutive(elements);
|
|
6293
6354
|
return (range) => {
|
|
6294
|
-
if (range.sheetId
|
|
6355
|
+
if (!isSheetNameEqual(range.sheetId, cmd.sheetId)) {
|
|
6295
6356
|
return { changeType: "NONE" };
|
|
6296
6357
|
}
|
|
6297
6358
|
let newRange = range;
|
|
@@ -6498,60 +6559,6 @@
|
|
|
6498
6559
|
return results.map((r) => r.elem);
|
|
6499
6560
|
}
|
|
6500
6561
|
|
|
6501
|
-
function createDefaultRows(rowNumber) {
|
|
6502
|
-
const rows = [];
|
|
6503
|
-
for (let i = 0; i < rowNumber; i++) {
|
|
6504
|
-
const row = {
|
|
6505
|
-
cells: {},
|
|
6506
|
-
};
|
|
6507
|
-
rows.push(row);
|
|
6508
|
-
}
|
|
6509
|
-
return rows;
|
|
6510
|
-
}
|
|
6511
|
-
function moveHeaderIndexesOnHeaderAddition(indexHeaderAdded, numberAdded, headers) {
|
|
6512
|
-
return headers.map((header) => {
|
|
6513
|
-
if (header >= indexHeaderAdded) {
|
|
6514
|
-
return header + numberAdded;
|
|
6515
|
-
}
|
|
6516
|
-
return header;
|
|
6517
|
-
});
|
|
6518
|
-
}
|
|
6519
|
-
function moveHeaderIndexesOnHeaderDeletion(deletedHeaders, headers) {
|
|
6520
|
-
deletedHeaders = [...deletedHeaders].sort((a, b) => b - a);
|
|
6521
|
-
return headers
|
|
6522
|
-
.map((header) => {
|
|
6523
|
-
for (const deletedHeader of deletedHeaders) {
|
|
6524
|
-
if (header > deletedHeader) {
|
|
6525
|
-
header--;
|
|
6526
|
-
}
|
|
6527
|
-
else if (header === deletedHeader) {
|
|
6528
|
-
return undefined;
|
|
6529
|
-
}
|
|
6530
|
-
}
|
|
6531
|
-
return header;
|
|
6532
|
-
})
|
|
6533
|
-
.filter(isDefined);
|
|
6534
|
-
}
|
|
6535
|
-
function getNextSheetName(existingNames, baseName = "Sheet") {
|
|
6536
|
-
let i = 1;
|
|
6537
|
-
let name = `${baseName}${i}`;
|
|
6538
|
-
while (existingNames.includes(name)) {
|
|
6539
|
-
name = `${baseName}${i}`;
|
|
6540
|
-
i++;
|
|
6541
|
-
}
|
|
6542
|
-
return name;
|
|
6543
|
-
}
|
|
6544
|
-
function getDuplicateSheetName(nameToDuplicate, existingNames) {
|
|
6545
|
-
let i = 1;
|
|
6546
|
-
const baseName = _t("Copy of %s", nameToDuplicate);
|
|
6547
|
-
let name = baseName.toString();
|
|
6548
|
-
while (existingNames.includes(name)) {
|
|
6549
|
-
name = `${baseName} (${i})`;
|
|
6550
|
-
i++;
|
|
6551
|
-
}
|
|
6552
|
-
return name;
|
|
6553
|
-
}
|
|
6554
|
-
|
|
6555
6562
|
function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
|
|
6556
6563
|
return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
|
|
6557
6564
|
}
|
|
@@ -8308,7 +8315,8 @@
|
|
|
8308
8315
|
};
|
|
8309
8316
|
},
|
|
8310
8317
|
toFunctionValue(normalizedValue) {
|
|
8311
|
-
|
|
8318
|
+
const jsDate = toJsDate(normalizedValue, DEFAULT_LOCALE);
|
|
8319
|
+
return `DATE(${jsDate.getFullYear()},${jsDate.getMonth() + 1},1)`;
|
|
8312
8320
|
},
|
|
8313
8321
|
};
|
|
8314
8322
|
/**
|
|
@@ -8463,10 +8471,9 @@
|
|
|
8463
8471
|
avg: _t("Average"),
|
|
8464
8472
|
sum: _t("Sum"),
|
|
8465
8473
|
};
|
|
8466
|
-
const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
|
|
8467
8474
|
const AGGREGATORS_BY_FIELD_TYPE = {
|
|
8468
|
-
integer:
|
|
8469
|
-
char:
|
|
8475
|
+
integer: ["max", "min", "avg", "sum", "count_distinct", "count"],
|
|
8476
|
+
char: ["count_distinct", "count"],
|
|
8470
8477
|
boolean: ["count_distinct", "count", "bool_and", "bool_or"],
|
|
8471
8478
|
datetime: ["max", "min", "count_distinct", "count"],
|
|
8472
8479
|
};
|
|
@@ -9834,7 +9841,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9834
9841
|
const functionProxy = new Proxy(value, {
|
|
9835
9842
|
// trap the function call
|
|
9836
9843
|
apply(target, thisArg, argArray) {
|
|
9837
|
-
Reflect.apply(target, thisStore, argArray);
|
|
9844
|
+
const res = Reflect.apply(target, thisStore, argArray);
|
|
9845
|
+
if (res === "noStateChange") {
|
|
9846
|
+
return;
|
|
9847
|
+
}
|
|
9838
9848
|
callback();
|
|
9839
9849
|
},
|
|
9840
9850
|
});
|
|
@@ -9856,7 +9866,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9856
9866
|
const ModelStore = createAbstractStore("Model");
|
|
9857
9867
|
|
|
9858
9868
|
class RendererStore {
|
|
9859
|
-
mutators = ["register", "unRegister"];
|
|
9869
|
+
mutators = ["register", "unRegister", "drawLayer"];
|
|
9860
9870
|
renderers = {};
|
|
9861
9871
|
register(renderer) {
|
|
9862
9872
|
if (!renderer.renderingLayers.length) {
|
|
@@ -9876,14 +9886,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9876
9886
|
}
|
|
9877
9887
|
drawLayer(context, layer) {
|
|
9878
9888
|
const renderers = this.renderers[layer];
|
|
9879
|
-
if (
|
|
9880
|
-
|
|
9881
|
-
|
|
9882
|
-
|
|
9883
|
-
|
|
9884
|
-
|
|
9885
|
-
context.ctx.restore();
|
|
9889
|
+
if (renderers) {
|
|
9890
|
+
for (const renderer of renderers) {
|
|
9891
|
+
context.ctx.save();
|
|
9892
|
+
renderer.drawLayer(context, layer);
|
|
9893
|
+
context.ctx.restore();
|
|
9894
|
+
}
|
|
9886
9895
|
}
|
|
9896
|
+
return "noStateChange";
|
|
9887
9897
|
}
|
|
9888
9898
|
}
|
|
9889
9899
|
|
|
@@ -9936,16 +9946,17 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9936
9946
|
focusComposer(listener, args) {
|
|
9937
9947
|
this.activeComposer = listener;
|
|
9938
9948
|
if (this.getters.isReadonly()) {
|
|
9939
|
-
return;
|
|
9949
|
+
return "noStateChange";
|
|
9940
9950
|
}
|
|
9941
9951
|
this._focusMode = args.focusMode || "contentFocus";
|
|
9942
9952
|
if (this._focusMode !== "inactive") {
|
|
9943
9953
|
this.setComposerContent(args);
|
|
9944
9954
|
}
|
|
9955
|
+
return;
|
|
9945
9956
|
}
|
|
9946
9957
|
focusActiveComposer(args) {
|
|
9947
9958
|
if (this.getters.isReadonly()) {
|
|
9948
|
-
return;
|
|
9959
|
+
return "noStateChange";
|
|
9949
9960
|
}
|
|
9950
9961
|
if (!this.activeComposer) {
|
|
9951
9962
|
throw new Error("No composer is registered");
|
|
@@ -9954,6 +9965,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9954
9965
|
if (this._focusMode !== "inactive") {
|
|
9955
9966
|
this.setComposerContent(args);
|
|
9956
9967
|
}
|
|
9968
|
+
return;
|
|
9957
9969
|
}
|
|
9958
9970
|
/**
|
|
9959
9971
|
* Start the edition or update the content if it's already started.
|
|
@@ -10557,7 +10569,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10557
10569
|
}
|
|
10558
10570
|
function formatChartDatasetValue(axisFormats, locale) {
|
|
10559
10571
|
return (value, axisId) => {
|
|
10560
|
-
const format =
|
|
10572
|
+
const format = axisFormats?.[axisId];
|
|
10561
10573
|
return formatTickValue({ format, locale })(value);
|
|
10562
10574
|
};
|
|
10563
10575
|
}
|
|
@@ -10734,7 +10746,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10734
10746
|
const y = bar.y + midRadius * Math.sin(midAngle) + 7;
|
|
10735
10747
|
ctx.fillStyle = chartFontColor(options.background);
|
|
10736
10748
|
ctx.strokeStyle = options.background || "#ffffff";
|
|
10737
|
-
const displayValue = options.callback(value);
|
|
10749
|
+
const displayValue = options.callback(value, "y");
|
|
10738
10750
|
drawTextWithBackground(displayValue, x, y, ctx);
|
|
10739
10751
|
}
|
|
10740
10752
|
}
|
|
@@ -20543,6 +20555,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20543
20555
|
};
|
|
20544
20556
|
}
|
|
20545
20557
|
const domain = pivot.parseArgsToPivotDomain(domainArgs);
|
|
20558
|
+
if (this.getters.getActiveSheetId() === this.__originSheetId) {
|
|
20559
|
+
this.getters.getPivotPresenceTracker(pivotId)?.trackValue(_measure, domain);
|
|
20560
|
+
}
|
|
20546
20561
|
return pivot.getPivotCellValueAndFormat(_measure, domain);
|
|
20547
20562
|
},
|
|
20548
20563
|
};
|
|
@@ -20574,6 +20589,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20574
20589
|
};
|
|
20575
20590
|
}
|
|
20576
20591
|
const domain = pivot.parseArgsToPivotDomain(domainArgs);
|
|
20592
|
+
if (this.getters.getActiveSheetId() === this.__originSheetId) {
|
|
20593
|
+
this.getters.getPivotPresenceTracker(_pivotId)?.trackHeader(domain);
|
|
20594
|
+
}
|
|
20577
20595
|
const lastNode = domain.at(-1);
|
|
20578
20596
|
if (lastNode?.field === "measure") {
|
|
20579
20597
|
return pivot.getPivotMeasureValue(toString(lastNode.value), domain);
|
|
@@ -20796,6 +20814,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20796
20814
|
return data === undefined || data.value === null;
|
|
20797
20815
|
}
|
|
20798
20816
|
const getNeutral = { number: 0, string: "", boolean: false };
|
|
20817
|
+
function areAlmostEqual(value1, value2, epsilon = 2e-16) {
|
|
20818
|
+
return Math.abs(value1 - value2) < epsilon;
|
|
20819
|
+
}
|
|
20799
20820
|
const EQ = {
|
|
20800
20821
|
description: _t("Equal."),
|
|
20801
20822
|
args: [
|
|
@@ -20817,6 +20838,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20817
20838
|
if (typeof _value2 === "string") {
|
|
20818
20839
|
_value2 = _value2.toUpperCase();
|
|
20819
20840
|
}
|
|
20841
|
+
if (typeof _value1 === "number" && typeof _value2 === "number") {
|
|
20842
|
+
return { value: areAlmostEqual(_value1, _value2) };
|
|
20843
|
+
}
|
|
20820
20844
|
return { value: _value1 === _value2 };
|
|
20821
20845
|
},
|
|
20822
20846
|
};
|
|
@@ -20856,6 +20880,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20856
20880
|
],
|
|
20857
20881
|
compute: function (value1, value2) {
|
|
20858
20882
|
return applyRelationalOperator(value1, value2, (v1, v2) => {
|
|
20883
|
+
if (typeof v1 === "number" && typeof v2 === "number") {
|
|
20884
|
+
return !areAlmostEqual(v1, v2) && v1 > v2;
|
|
20885
|
+
}
|
|
20859
20886
|
return v1 > v2;
|
|
20860
20887
|
});
|
|
20861
20888
|
},
|
|
@@ -20871,6 +20898,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20871
20898
|
],
|
|
20872
20899
|
compute: function (value1, value2) {
|
|
20873
20900
|
return applyRelationalOperator(value1, value2, (v1, v2) => {
|
|
20901
|
+
if (typeof v1 === "number" && typeof v2 === "number") {
|
|
20902
|
+
return areAlmostEqual(v1, v2) || v1 > v2;
|
|
20903
|
+
}
|
|
20874
20904
|
return v1 >= v2;
|
|
20875
20905
|
});
|
|
20876
20906
|
},
|
|
@@ -22563,7 +22593,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22563
22593
|
.find((token) => {
|
|
22564
22594
|
const { xc, sheetName: sheet } = splitReference(token.value);
|
|
22565
22595
|
const sheetName = sheet || this.getters.getSheetName(this.sheetId);
|
|
22566
|
-
if (this.getters.getSheetName(activeSheetId)
|
|
22596
|
+
if (!isSheetNameEqual(this.getters.getSheetName(activeSheetId), sheetName)) {
|
|
22567
22597
|
return false;
|
|
22568
22598
|
}
|
|
22569
22599
|
const refRange = this.getters.getRangeFromSheetXC(activeSheetId, xc);
|
|
@@ -24500,6 +24530,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
24500
24530
|
const div = document.createElement("div");
|
|
24501
24531
|
div.style.width = `${figure.width}px`;
|
|
24502
24532
|
div.style.height = `${figure.height}px`;
|
|
24533
|
+
div.style.position = "fixed";
|
|
24534
|
+
div.style.opacity = "0";
|
|
24503
24535
|
const canvas = document.createElement("canvas");
|
|
24504
24536
|
div.append(canvas);
|
|
24505
24537
|
canvas.setAttribute("width", figure.width.toString());
|
|
@@ -29702,10 +29734,15 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29702
29734
|
const imageUrl = chartToImageUrl(runtime, figure, chartType);
|
|
29703
29735
|
const innerHTML = `<img src="${xmlEscape(imageUrl)}" />`;
|
|
29704
29736
|
const blob = await chartToImageFile(runtime, figure, chartType);
|
|
29705
|
-
env.clipboard.write({
|
|
29737
|
+
await env.clipboard.write({
|
|
29706
29738
|
"text/html": innerHTML,
|
|
29707
29739
|
"image/png": blob,
|
|
29708
29740
|
});
|
|
29741
|
+
env.notifyUser({
|
|
29742
|
+
text: _t("The chart was copied to your clipboard"),
|
|
29743
|
+
sticky: false,
|
|
29744
|
+
type: "info",
|
|
29745
|
+
});
|
|
29709
29746
|
},
|
|
29710
29747
|
},
|
|
29711
29748
|
{
|
|
@@ -31555,7 +31592,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
31555
31592
|
({ xc, sheetName } = splitReference(reference));
|
|
31556
31593
|
let rangeSheetIndex;
|
|
31557
31594
|
if (sheetName) {
|
|
31558
|
-
const index = data.sheets.findIndex((sheet) => sheet.name
|
|
31595
|
+
const index = data.sheets.findIndex((sheet) => isSheetNameEqual(sheet.name, sheetName));
|
|
31559
31596
|
if (index < 0) {
|
|
31560
31597
|
throw new Error("Unable to find a sheet with the name " + sheetName);
|
|
31561
31598
|
}
|
|
@@ -31912,7 +31949,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
31912
31949
|
formula = formula.replace(externalReferenceRegex, (match, externalRefId, sheetName, cellRef) => {
|
|
31913
31950
|
externalRefId = Number(externalRefId) - 1;
|
|
31914
31951
|
cellRef = cellRef.replace(/\$/g, "");
|
|
31915
|
-
const sheetIndex = data.externalBooks[externalRefId].sheetNames.findIndex((name) => name
|
|
31952
|
+
const sheetIndex = data.externalBooks[externalRefId].sheetNames.findIndex((name) => isSheetNameEqual(name, sheetName));
|
|
31916
31953
|
if (sheetIndex === -1) {
|
|
31917
31954
|
return match;
|
|
31918
31955
|
}
|
|
@@ -32563,7 +32600,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32563
32600
|
*/
|
|
32564
32601
|
function convertTableFormulaReferences(convertedSheets, xlsxSheets) {
|
|
32565
32602
|
for (let tableSheet of convertedSheets) {
|
|
32566
|
-
const tables = xlsxSheets.find((s) => s.sheetName
|
|
32603
|
+
const tables = xlsxSheets.find((s) => isSheetNameEqual(s.sheetName, tableSheet.name)).tables;
|
|
32567
32604
|
for (let table of tables) {
|
|
32568
32605
|
const tabRef = table.name + "[";
|
|
32569
32606
|
for (let sheet of convertedSheets) {
|
|
@@ -35218,12 +35255,20 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35218
35255
|
}
|
|
35219
35256
|
}
|
|
35220
35257
|
hover(position) {
|
|
35258
|
+
if (position.col === this.col && position.row === this.row) {
|
|
35259
|
+
return "noStateChange";
|
|
35260
|
+
}
|
|
35221
35261
|
this.col = position.col;
|
|
35222
35262
|
this.row = position.row;
|
|
35263
|
+
return;
|
|
35223
35264
|
}
|
|
35224
35265
|
clear() {
|
|
35266
|
+
if (this.col === undefined && this.row === undefined) {
|
|
35267
|
+
return "noStateChange";
|
|
35268
|
+
}
|
|
35225
35269
|
this.col = undefined;
|
|
35226
35270
|
this.row = undefined;
|
|
35271
|
+
return;
|
|
35227
35272
|
}
|
|
35228
35273
|
}
|
|
35229
35274
|
|
|
@@ -35245,7 +35290,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35245
35290
|
this.persistentPopover = { col, row, sheetId, type };
|
|
35246
35291
|
}
|
|
35247
35292
|
close() {
|
|
35293
|
+
if (!this.persistentPopover) {
|
|
35294
|
+
return "noStateChange";
|
|
35295
|
+
}
|
|
35248
35296
|
this.persistentPopover = undefined;
|
|
35297
|
+
return;
|
|
35249
35298
|
}
|
|
35250
35299
|
get persistentCellPopover() {
|
|
35251
35300
|
return ((this.persistentPopover && { isOpen: true, ...this.persistentPopover }) || { isOpen: false });
|
|
@@ -42363,10 +42412,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
42363
42412
|
}
|
|
42364
42413
|
|
|
42365
42414
|
class DOMFocusableElementStore {
|
|
42366
|
-
mutators = ["setFocusableElement"];
|
|
42415
|
+
mutators = ["setFocusableElement", "focus"];
|
|
42367
42416
|
focusableElement = undefined;
|
|
42368
42417
|
setFocusableElement(element) {
|
|
42369
42418
|
this.focusableElement = element;
|
|
42419
|
+
return "noStateChange";
|
|
42420
|
+
}
|
|
42421
|
+
focus() {
|
|
42422
|
+
if (this.focusableElement === document.activeElement) {
|
|
42423
|
+
return "noStateChange";
|
|
42424
|
+
}
|
|
42425
|
+
this.focusableElement?.focus();
|
|
42426
|
+
return;
|
|
42370
42427
|
}
|
|
42371
42428
|
}
|
|
42372
42429
|
|
|
@@ -43038,7 +43095,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
43038
43095
|
if (document.activeElement === this.contentHelper.el &&
|
|
43039
43096
|
this.props.composerStore.editionMode === "inactive" &&
|
|
43040
43097
|
!this.props.isDefaultFocus) {
|
|
43041
|
-
this.DOMFocusableElementStore.
|
|
43098
|
+
this.DOMFocusableElementStore.focus();
|
|
43042
43099
|
}
|
|
43043
43100
|
});
|
|
43044
43101
|
owl.useEffect(() => {
|
|
@@ -49576,7 +49633,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
49576
49633
|
entry[field.name] = { value: null, type: CellValueType.empty, formattedValue: "" };
|
|
49577
49634
|
}
|
|
49578
49635
|
else {
|
|
49579
|
-
|
|
49636
|
+
if (field.type === "char") {
|
|
49637
|
+
entry[field.name] = { ...cell, value: cell.formattedValue || null };
|
|
49638
|
+
}
|
|
49639
|
+
else {
|
|
49640
|
+
entry[field.name] = cell;
|
|
49641
|
+
}
|
|
49580
49642
|
}
|
|
49581
49643
|
}
|
|
49582
49644
|
entry["__count"] = { value: 1, type: CellValueType.number, formattedValue: "1" };
|
|
@@ -53301,9 +53363,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
53301
53363
|
}
|
|
53302
53364
|
}
|
|
53303
53365
|
hover(position) {
|
|
53366
|
+
if (position.col === this.col && position.row === this.row) {
|
|
53367
|
+
return "noStateChange";
|
|
53368
|
+
}
|
|
53304
53369
|
this.col = position.col;
|
|
53305
53370
|
this.row = position.row;
|
|
53306
53371
|
this.computeOverlay();
|
|
53372
|
+
return;
|
|
53307
53373
|
}
|
|
53308
53374
|
clear() {
|
|
53309
53375
|
this.col = undefined;
|
|
@@ -54935,10 +55001,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
54935
55001
|
ctx.scale(dpr, dpr);
|
|
54936
55002
|
for (const layer of OrderedLayers()) {
|
|
54937
55003
|
model.drawLayer(renderingContext, layer);
|
|
54938
|
-
// @ts-ignore 'drawLayer' is not declated as a mutator because:
|
|
54939
|
-
// it does not mutate anything. Most importantly it's used
|
|
54940
|
-
// during rendering. Invoking a mutator during rendering would
|
|
54941
|
-
// trigger another rendering, ultimately resulting in an infinite loop.
|
|
54942
55004
|
rendererStore.drawLayer(renderingContext, layer);
|
|
54943
55005
|
}
|
|
54944
55006
|
}
|
|
@@ -55632,7 +55694,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
55632
55694
|
this.cellPopovers = useStore(CellPopoverStore);
|
|
55633
55695
|
owl.useEffect(() => {
|
|
55634
55696
|
if (!this.sidePanel.isOpen) {
|
|
55635
|
-
this.DOMFocusableElementStore.
|
|
55697
|
+
this.DOMFocusableElementStore.focus();
|
|
55636
55698
|
}
|
|
55637
55699
|
}, () => [this.sidePanel.isOpen]);
|
|
55638
55700
|
useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
|
|
@@ -55841,7 +55903,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
55841
55903
|
focusDefaultElement() {
|
|
55842
55904
|
if (!this.env.model.getters.getSelectedFigureId() &&
|
|
55843
55905
|
this.composerFocusStore.activeComposer.editionMode === "inactive") {
|
|
55844
|
-
this.DOMFocusableElementStore.
|
|
55906
|
+
this.DOMFocusableElementStore.focus();
|
|
55845
55907
|
}
|
|
55846
55908
|
}
|
|
55847
55909
|
get gridEl() {
|
|
@@ -56190,6 +56252,322 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
56190
56252
|
}
|
|
56191
56253
|
}
|
|
56192
56254
|
|
|
56255
|
+
css /* scss */ `
|
|
56256
|
+
.o_pivot_html_renderer {
|
|
56257
|
+
width: 100%;
|
|
56258
|
+
border-collapse: collapse;
|
|
56259
|
+
|
|
56260
|
+
&:hover {
|
|
56261
|
+
cursor: pointer;
|
|
56262
|
+
}
|
|
56263
|
+
|
|
56264
|
+
td,
|
|
56265
|
+
th {
|
|
56266
|
+
border: 1px solid #dee2e6;
|
|
56267
|
+
background-color: #fff;
|
|
56268
|
+
padding: 0.3rem;
|
|
56269
|
+
white-space: nowrap;
|
|
56270
|
+
|
|
56271
|
+
&:hover {
|
|
56272
|
+
filter: brightness(0.9);
|
|
56273
|
+
}
|
|
56274
|
+
}
|
|
56275
|
+
|
|
56276
|
+
td {
|
|
56277
|
+
text-align: right;
|
|
56278
|
+
}
|
|
56279
|
+
|
|
56280
|
+
th {
|
|
56281
|
+
background-color: #f5f5f5;
|
|
56282
|
+
font-weight: bold;
|
|
56283
|
+
color: black;
|
|
56284
|
+
}
|
|
56285
|
+
|
|
56286
|
+
.o_missing_value {
|
|
56287
|
+
color: #46646d;
|
|
56288
|
+
background: #e7f2f6;
|
|
56289
|
+
}
|
|
56290
|
+
}
|
|
56291
|
+
`;
|
|
56292
|
+
class PivotHTMLRenderer extends owl.Component {
|
|
56293
|
+
static template = "o_spreadsheet.PivotHTMLRenderer";
|
|
56294
|
+
static components = { Checkbox };
|
|
56295
|
+
static props = {
|
|
56296
|
+
pivotId: String,
|
|
56297
|
+
onCellClicked: Function,
|
|
56298
|
+
};
|
|
56299
|
+
pivot = this.env.model.getters.getPivot(this.props.pivotId);
|
|
56300
|
+
data = {
|
|
56301
|
+
columns: [],
|
|
56302
|
+
rows: [],
|
|
56303
|
+
values: [],
|
|
56304
|
+
};
|
|
56305
|
+
state = owl.useState({
|
|
56306
|
+
showMissingValuesOnly: false,
|
|
56307
|
+
});
|
|
56308
|
+
setup() {
|
|
56309
|
+
const table = this.pivot.getTableStructure();
|
|
56310
|
+
const formulaId = this.env.model.getters.getPivotFormulaId(this.props.pivotId);
|
|
56311
|
+
this.data = {
|
|
56312
|
+
columns: this._buildColHeaders(formulaId, table),
|
|
56313
|
+
rows: this._buildRowHeaders(formulaId, table),
|
|
56314
|
+
values: this._buildValues(formulaId, table),
|
|
56315
|
+
};
|
|
56316
|
+
}
|
|
56317
|
+
get tracker() {
|
|
56318
|
+
return this.env.model.getters.getPivotPresenceTracker(this.props.pivotId);
|
|
56319
|
+
}
|
|
56320
|
+
// ---------------------------------------------------------------------
|
|
56321
|
+
// Missing values building
|
|
56322
|
+
// ---------------------------------------------------------------------
|
|
56323
|
+
/**
|
|
56324
|
+
* Retrieve the data to display in the Pivot Table
|
|
56325
|
+
* In the case when showMissingValuesOnly is false, the returned value
|
|
56326
|
+
* is the complete data
|
|
56327
|
+
* In the case when showMissingValuesOnly is true, the returned value is
|
|
56328
|
+
* the data which contains only missing values in the rows and cols. In
|
|
56329
|
+
* the rows, we also return the parent rows of rows which contains missing
|
|
56330
|
+
* values, to give context to the user.
|
|
56331
|
+
*
|
|
56332
|
+
*/
|
|
56333
|
+
getTableData() {
|
|
56334
|
+
if (!this.state.showMissingValuesOnly) {
|
|
56335
|
+
return this.data;
|
|
56336
|
+
}
|
|
56337
|
+
const colIndexes = this.getColumnsIndexes();
|
|
56338
|
+
const rowIndexes = this.getRowsIndexes();
|
|
56339
|
+
const columns = this.buildColumnsMissing(colIndexes);
|
|
56340
|
+
const rows = this.buildRowsMissing(rowIndexes);
|
|
56341
|
+
const values = this.buildValuesMissing(colIndexes, rowIndexes);
|
|
56342
|
+
return { columns, rows, values };
|
|
56343
|
+
}
|
|
56344
|
+
/**
|
|
56345
|
+
* Retrieve the parents of the given row
|
|
56346
|
+
* ex:
|
|
56347
|
+
* Australia
|
|
56348
|
+
* January
|
|
56349
|
+
* February
|
|
56350
|
+
* The parent of "January" is "Australia"
|
|
56351
|
+
*/
|
|
56352
|
+
addRecursiveRow(index) {
|
|
56353
|
+
const rows = this.pivot.getTableStructure().rows;
|
|
56354
|
+
const row = [...rows[index].values];
|
|
56355
|
+
if (row.length <= 1) {
|
|
56356
|
+
return [index];
|
|
56357
|
+
}
|
|
56358
|
+
row.pop();
|
|
56359
|
+
const parentRowIndex = rows.findIndex((r) => JSON.stringify(r.values) === JSON.stringify(row));
|
|
56360
|
+
return [index].concat(this.addRecursiveRow(parentRowIndex));
|
|
56361
|
+
}
|
|
56362
|
+
/**
|
|
56363
|
+
* Create the columns to be used, based on the indexes of the columns in
|
|
56364
|
+
* which a missing value is present
|
|
56365
|
+
*
|
|
56366
|
+
*/
|
|
56367
|
+
buildColumnsMissing(indexes) {
|
|
56368
|
+
// columnsMap explode the columns in an array of array of the same
|
|
56369
|
+
// size with the index of each column, repeated 'span' times.
|
|
56370
|
+
// ex:
|
|
56371
|
+
// | A | B |
|
|
56372
|
+
// | 1 | 2 | 3 |
|
|
56373
|
+
// => [
|
|
56374
|
+
// [0, 0, 1]
|
|
56375
|
+
// [0, 1, 2]
|
|
56376
|
+
// ]
|
|
56377
|
+
const columnsMap = [];
|
|
56378
|
+
for (const column of this.data.columns) {
|
|
56379
|
+
const columnMap = [];
|
|
56380
|
+
for (const index in column) {
|
|
56381
|
+
for (let i = 0; i < column[index].span; i++) {
|
|
56382
|
+
columnMap.push(parseInt(index, 10));
|
|
56383
|
+
}
|
|
56384
|
+
}
|
|
56385
|
+
columnsMap.push(columnMap);
|
|
56386
|
+
}
|
|
56387
|
+
// Remove the columns that are not present in indexes
|
|
56388
|
+
for (let i = columnsMap[columnsMap.length - 1].length; i >= 0; i--) {
|
|
56389
|
+
if (!indexes.includes(i)) {
|
|
56390
|
+
for (const columnMap of columnsMap) {
|
|
56391
|
+
columnMap.splice(i, 1);
|
|
56392
|
+
}
|
|
56393
|
+
}
|
|
56394
|
+
}
|
|
56395
|
+
// Build the columns
|
|
56396
|
+
const columns = [];
|
|
56397
|
+
for (const mapIndex in columnsMap) {
|
|
56398
|
+
const column = [];
|
|
56399
|
+
let index = undefined;
|
|
56400
|
+
let span = 1;
|
|
56401
|
+
for (let i = 0; i < columnsMap[mapIndex].length; i++) {
|
|
56402
|
+
if (index !== columnsMap[mapIndex][i]) {
|
|
56403
|
+
if (index !== undefined) {
|
|
56404
|
+
column.push(Object.assign({}, this.data.columns[mapIndex][index], { span }));
|
|
56405
|
+
}
|
|
56406
|
+
index = columnsMap[mapIndex][i];
|
|
56407
|
+
span = 1;
|
|
56408
|
+
}
|
|
56409
|
+
else {
|
|
56410
|
+
span++;
|
|
56411
|
+
}
|
|
56412
|
+
}
|
|
56413
|
+
if (index !== undefined) {
|
|
56414
|
+
column.push(Object.assign({}, this.data.columns[mapIndex][index], { span }));
|
|
56415
|
+
}
|
|
56416
|
+
columns.push(column);
|
|
56417
|
+
}
|
|
56418
|
+
return columns;
|
|
56419
|
+
}
|
|
56420
|
+
/**
|
|
56421
|
+
* Create the rows to be used, based on the indexes of the rows in
|
|
56422
|
+
* which a missing value is present.
|
|
56423
|
+
*/
|
|
56424
|
+
buildRowsMissing(indexes) {
|
|
56425
|
+
return indexes.map((index) => this.data.rows[index]);
|
|
56426
|
+
}
|
|
56427
|
+
/**
|
|
56428
|
+
* Create the value to be used, based on the indexes of the columns and
|
|
56429
|
+
* rows in which a missing value is present.
|
|
56430
|
+
*/
|
|
56431
|
+
buildValuesMissing(colIndexes, rowIndexes) {
|
|
56432
|
+
const values = colIndexes.map(() => []);
|
|
56433
|
+
for (const row of rowIndexes) {
|
|
56434
|
+
for (const col in colIndexes) {
|
|
56435
|
+
values[col].push(this.data.values[colIndexes[col]][row]);
|
|
56436
|
+
}
|
|
56437
|
+
}
|
|
56438
|
+
return values;
|
|
56439
|
+
}
|
|
56440
|
+
getColumnsIndexes() {
|
|
56441
|
+
const indexes = new Set();
|
|
56442
|
+
for (let i = 0; i < this.data.columns.length; i++) {
|
|
56443
|
+
const exploded = [];
|
|
56444
|
+
for (let y = 0; y < this.data.columns[i].length; y++) {
|
|
56445
|
+
for (let x = 0; x < this.data.columns[i][y].span; x++) {
|
|
56446
|
+
exploded.push(this.data.columns[i][y]);
|
|
56447
|
+
}
|
|
56448
|
+
}
|
|
56449
|
+
for (let y = 0; y < exploded.length; y++) {
|
|
56450
|
+
if (exploded[y].isMissing) {
|
|
56451
|
+
indexes.add(y);
|
|
56452
|
+
}
|
|
56453
|
+
}
|
|
56454
|
+
}
|
|
56455
|
+
for (let i = 0; i < this.data.columns[this.data.columns.length - 1].length; i++) {
|
|
56456
|
+
const values = this.data.values[i];
|
|
56457
|
+
if (values.find((x) => x.isMissing)) {
|
|
56458
|
+
indexes.add(i);
|
|
56459
|
+
}
|
|
56460
|
+
}
|
|
56461
|
+
return Array.from(indexes).sort((a, b) => a - b);
|
|
56462
|
+
}
|
|
56463
|
+
getRowsIndexes() {
|
|
56464
|
+
const rowIndexes = new Set();
|
|
56465
|
+
for (let i = 0; i < this.data.rows.length; i++) {
|
|
56466
|
+
if (this.data.rows[i].isMissing) {
|
|
56467
|
+
rowIndexes.add(i);
|
|
56468
|
+
}
|
|
56469
|
+
for (const col of this.data.values) {
|
|
56470
|
+
if (col[i].isMissing) {
|
|
56471
|
+
this.addRecursiveRow(i).forEach((x) => rowIndexes.add(x));
|
|
56472
|
+
}
|
|
56473
|
+
}
|
|
56474
|
+
}
|
|
56475
|
+
return Array.from(rowIndexes).sort((a, b) => a - b);
|
|
56476
|
+
}
|
|
56477
|
+
// ---------------------------------------------------------------------
|
|
56478
|
+
// Data table creation
|
|
56479
|
+
// ---------------------------------------------------------------------
|
|
56480
|
+
_buildColHeaders(id, table) {
|
|
56481
|
+
const headers = [];
|
|
56482
|
+
for (const row of table.columns) {
|
|
56483
|
+
const current = [];
|
|
56484
|
+
for (const cell of row) {
|
|
56485
|
+
const args = [];
|
|
56486
|
+
for (let i = 0; i < cell.fields.length; i++) {
|
|
56487
|
+
args.push({ value: cell.fields[i] }, { value: cell.values[i] });
|
|
56488
|
+
}
|
|
56489
|
+
const domain = this.pivot.parseArgsToPivotDomain(args);
|
|
56490
|
+
const locale = this.env.model.getters.getLocale();
|
|
56491
|
+
if (domain.at(-1)?.field === "measure") {
|
|
56492
|
+
const { value, format } = this.pivot.getPivotMeasureValue(toString(domain.at(-1).value), domain);
|
|
56493
|
+
current.push({
|
|
56494
|
+
formula: `=PIVOT.HEADER(${generatePivotArgs(id, domain).join(",")})`,
|
|
56495
|
+
value: formatValue(value, { format, locale }),
|
|
56496
|
+
span: cell.width,
|
|
56497
|
+
isMissing: !this.tracker?.isHeaderPresent(domain),
|
|
56498
|
+
});
|
|
56499
|
+
}
|
|
56500
|
+
else {
|
|
56501
|
+
const { value, format } = this.pivot.getPivotHeaderValueAndFormat(domain);
|
|
56502
|
+
current.push({
|
|
56503
|
+
formula: `=PIVOT.HEADER(${generatePivotArgs(id, domain).join(",")})`,
|
|
56504
|
+
value: formatValue(value, { format, locale }),
|
|
56505
|
+
span: cell.width,
|
|
56506
|
+
isMissing: !this.tracker?.isHeaderPresent(domain),
|
|
56507
|
+
});
|
|
56508
|
+
}
|
|
56509
|
+
}
|
|
56510
|
+
headers.push(current);
|
|
56511
|
+
}
|
|
56512
|
+
const last = headers[headers.length - 1];
|
|
56513
|
+
headers[headers.length - 1] = last.map((cell) => {
|
|
56514
|
+
if (!cell.isMissing) {
|
|
56515
|
+
cell.style = "color: #756f6f;";
|
|
56516
|
+
}
|
|
56517
|
+
return cell;
|
|
56518
|
+
});
|
|
56519
|
+
return headers;
|
|
56520
|
+
}
|
|
56521
|
+
_buildRowHeaders(id, table) {
|
|
56522
|
+
const headers = [];
|
|
56523
|
+
for (const row of table.rows) {
|
|
56524
|
+
const args = [];
|
|
56525
|
+
for (let i = 0; i < row.fields.length; i++) {
|
|
56526
|
+
args.push({ value: row.fields[i] }, { value: row.values[i] });
|
|
56527
|
+
}
|
|
56528
|
+
const domain = this.pivot.parseArgsToPivotDomain(args);
|
|
56529
|
+
const { value, format } = this.pivot.getPivotHeaderValueAndFormat(domain);
|
|
56530
|
+
const locale = this.env.model.getters.getLocale();
|
|
56531
|
+
const cell = {
|
|
56532
|
+
formula: `=PIVOT.HEADER(${generatePivotArgs(id, domain).join(",")})`,
|
|
56533
|
+
value: formatValue(value, { format, locale }),
|
|
56534
|
+
isMissing: !this.tracker?.isHeaderPresent(domain),
|
|
56535
|
+
};
|
|
56536
|
+
if (row.indent > 1) {
|
|
56537
|
+
cell.style = `padding-left: ${row.indent - 1 * 10}px`;
|
|
56538
|
+
}
|
|
56539
|
+
headers.push(cell);
|
|
56540
|
+
}
|
|
56541
|
+
return headers;
|
|
56542
|
+
}
|
|
56543
|
+
_buildValues(id, table) {
|
|
56544
|
+
const values = [];
|
|
56545
|
+
for (const col of table.columns.at(-1) || []) {
|
|
56546
|
+
const current = [];
|
|
56547
|
+
const measure = toString(col.values[col.values.length - 1]);
|
|
56548
|
+
for (const row of table.rows) {
|
|
56549
|
+
const args = [];
|
|
56550
|
+
for (let i = 0; i < row.fields.length; i++) {
|
|
56551
|
+
args.push({ value: row.fields[i] }, { value: row.values[i] });
|
|
56552
|
+
}
|
|
56553
|
+
for (let i = 0; i < col.fields.length - 1; i++) {
|
|
56554
|
+
args.push({ value: col.fields[i] }, { value: col.values[i] });
|
|
56555
|
+
}
|
|
56556
|
+
const domain = this.pivot.parseArgsToPivotDomain(args);
|
|
56557
|
+
const { value, format } = this.pivot.getPivotCellValueAndFormat(measure, domain);
|
|
56558
|
+
const locale = this.env.model.getters.getLocale();
|
|
56559
|
+
current.push({
|
|
56560
|
+
formula: `=PIVOT.VALUE(${generatePivotArgs(id, domain, measure).join(",")})`,
|
|
56561
|
+
value: formatValue(value, { format, locale }),
|
|
56562
|
+
isMissing: !this.tracker?.isValuePresent(measure, domain),
|
|
56563
|
+
});
|
|
56564
|
+
}
|
|
56565
|
+
values.push(current);
|
|
56566
|
+
}
|
|
56567
|
+
return values;
|
|
56568
|
+
}
|
|
56569
|
+
}
|
|
56570
|
+
|
|
56193
56571
|
/**
|
|
56194
56572
|
* BasePlugin
|
|
56195
56573
|
*
|
|
@@ -60209,7 +60587,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
60209
60587
|
if (name) {
|
|
60210
60588
|
const unquotedName = getUnquotedSheetName(name);
|
|
60211
60589
|
for (const key in this.sheetIdsMapName) {
|
|
60212
|
-
if (key
|
|
60590
|
+
if (isSheetNameEqual(key, unquotedName)) {
|
|
60213
60591
|
return this.sheetIdsMapName[key];
|
|
60214
60592
|
}
|
|
60215
60593
|
}
|
|
@@ -60458,7 +60836,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
60458
60836
|
}
|
|
60459
60837
|
const { orderedSheetIds, sheets } = this;
|
|
60460
60838
|
const name = sheetName && sheetName.trim().toLowerCase();
|
|
60461
|
-
if (orderedSheetIds.find((id) => sheets[id]?.name
|
|
60839
|
+
if (orderedSheetIds.find((id) => isSheetNameEqual(sheets[id]?.name, name) && id !== cmd.sheetId)) {
|
|
60462
60840
|
return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
|
|
60463
60841
|
}
|
|
60464
60842
|
if (FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX.test(name)) {
|
|
@@ -69542,6 +69920,55 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
69542
69920
|
}
|
|
69543
69921
|
}
|
|
69544
69922
|
|
|
69923
|
+
class PivotPresenceTracker {
|
|
69924
|
+
trackedValues = new Set();
|
|
69925
|
+
domainToArray(domain) {
|
|
69926
|
+
return domain.flatMap((node) => [node.field, toString(node.value)]);
|
|
69927
|
+
}
|
|
69928
|
+
isValuePresent(measure, domain) {
|
|
69929
|
+
const key = JSON.stringify({ measure, domain: this.domainToArray(domain) });
|
|
69930
|
+
return this.trackedValues.has(key);
|
|
69931
|
+
}
|
|
69932
|
+
isHeaderPresent(domain) {
|
|
69933
|
+
const key = JSON.stringify({ domain: this.domainToArray(domain) });
|
|
69934
|
+
return this.trackedValues.has(key);
|
|
69935
|
+
}
|
|
69936
|
+
trackValue(measure, domain) {
|
|
69937
|
+
const key = JSON.stringify({ measure, domain: this.domainToArray(domain) });
|
|
69938
|
+
this.trackedValues.add(key);
|
|
69939
|
+
}
|
|
69940
|
+
trackHeader(domain) {
|
|
69941
|
+
const key = JSON.stringify({ domain: this.domainToArray(domain) });
|
|
69942
|
+
this.trackedValues.add(key);
|
|
69943
|
+
}
|
|
69944
|
+
}
|
|
69945
|
+
|
|
69946
|
+
class PivotPresencePlugin extends UIPlugin {
|
|
69947
|
+
static getters = ["getPivotPresenceTracker"];
|
|
69948
|
+
trackPresencePivotId;
|
|
69949
|
+
tracker;
|
|
69950
|
+
handle(cmd) {
|
|
69951
|
+
switch (cmd.type) {
|
|
69952
|
+
case "PIVOT_START_PRESENCE_TRACKING":
|
|
69953
|
+
this.tracker = new PivotPresenceTracker();
|
|
69954
|
+
this.trackPresencePivotId = cmd.pivotId;
|
|
69955
|
+
break;
|
|
69956
|
+
case "PIVOT_STOP_PRESENCE_TRACKING":
|
|
69957
|
+
this.trackPresencePivotId = undefined;
|
|
69958
|
+
break;
|
|
69959
|
+
}
|
|
69960
|
+
}
|
|
69961
|
+
getPivotPresenceTracker(pivotId) {
|
|
69962
|
+
if (this.trackPresencePivotId !== pivotId) {
|
|
69963
|
+
return undefined;
|
|
69964
|
+
}
|
|
69965
|
+
if (!this.tracker) {
|
|
69966
|
+
throw new Error("Tracker not initialized");
|
|
69967
|
+
}
|
|
69968
|
+
return this.tracker;
|
|
69969
|
+
}
|
|
69970
|
+
}
|
|
69971
|
+
|
|
69545
69972
|
class SplitToColumnsPlugin extends UIPlugin {
|
|
69546
69973
|
static getters = ["getAutomaticSeparator"];
|
|
69547
69974
|
allowDispatch(cmd) {
|
|
@@ -72510,6 +72937,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
72510
72937
|
.add("automatic_sum", AutomaticSumPlugin)
|
|
72511
72938
|
.add("format", FormatPlugin)
|
|
72512
72939
|
.add("insert_pivot", InsertPivotPlugin)
|
|
72940
|
+
.add("pivot_presence", PivotPresencePlugin)
|
|
72513
72941
|
.add("split_to_columns", SplitToColumnsPlugin)
|
|
72514
72942
|
.add("collaborative", CollaborativePlugin)
|
|
72515
72943
|
.add("history", HistoryPlugin)
|
|
@@ -72899,11 +73327,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
72899
73327
|
if (ev.key === "Enter") {
|
|
72900
73328
|
ev.preventDefault();
|
|
72901
73329
|
this.stopEdition();
|
|
72902
|
-
this.DOMFocusableElementStore.
|
|
73330
|
+
this.DOMFocusableElementStore.focus();
|
|
72903
73331
|
}
|
|
72904
73332
|
if (ev.key === "Escape") {
|
|
72905
73333
|
this.cancelEdition();
|
|
72906
|
-
this.DOMFocusableElementStore.
|
|
73334
|
+
this.DOMFocusableElementStore.focus();
|
|
72907
73335
|
}
|
|
72908
73336
|
}
|
|
72909
73337
|
onMouseEventSheetName(ev) {
|
|
@@ -79912,6 +80340,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
79912
80340
|
PivotDimensionOrder,
|
|
79913
80341
|
PivotDimension,
|
|
79914
80342
|
PivotLayoutConfigurator,
|
|
80343
|
+
PivotHTMLRenderer,
|
|
79915
80344
|
PivotDeferUpdate,
|
|
79916
80345
|
PivotTitleSection,
|
|
79917
80346
|
CogWheelMenu,
|
|
@@ -80009,9 +80438,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
80009
80438
|
exports.tokenize = tokenize;
|
|
80010
80439
|
|
|
80011
80440
|
|
|
80012
|
-
__info__.version = "18.3.
|
|
80013
|
-
__info__.date = "2025-05-
|
|
80014
|
-
__info__.hash = "
|
|
80441
|
+
__info__.version = "18.3.3";
|
|
80442
|
+
__info__.date = "2025-05-13T17:54:43.312Z";
|
|
80443
|
+
__info__.hash = "b79924a";
|
|
80015
80444
|
|
|
80016
80445
|
|
|
80017
80446
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|