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