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