@odoo/o-spreadsheet 18.1.1 → 18.2.0-alpha.1
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 +504 -355
- package/dist/o-spreadsheet.d.ts +66 -29
- package/dist/o-spreadsheet.esm.js +505 -357
- package/dist/o-spreadsheet.iife.js +504 -355
- package/dist/o-spreadsheet.iife.min.js +359 -348
- package/dist/o_spreadsheet.xml +3 -3
- package/package.json +2 -2
|
@@ -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.
|
|
6
|
-
* @date 2025-01-14T11:
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.2.0-alpha.1
|
|
6
|
+
* @date 2025-01-14T11:35:51.135Z
|
|
7
|
+
* @hash 702f816
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -356,6 +356,7 @@
|
|
|
356
356
|
ComponentsImportance[ComponentsImportance["Popover"] = 35] = "Popover";
|
|
357
357
|
ComponentsImportance[ComponentsImportance["FigureAnchor"] = 1000] = "FigureAnchor";
|
|
358
358
|
ComponentsImportance[ComponentsImportance["FigureSnapLine"] = 1001] = "FigureSnapLine";
|
|
359
|
+
ComponentsImportance[ComponentsImportance["FigureTooltip"] = 1002] = "FigureTooltip";
|
|
359
360
|
})(ComponentsImportance || (ComponentsImportance = {}));
|
|
360
361
|
let DEFAULT_SHEETVIEW_SIZE = 0;
|
|
361
362
|
function getDefaultSheetViewSize() {
|
|
@@ -975,6 +976,16 @@
|
|
|
975
976
|
}
|
|
976
977
|
return result;
|
|
977
978
|
}
|
|
979
|
+
function getUniqueText(text, texts, options = {}) {
|
|
980
|
+
const compute = options.compute ?? ((text, i) => `${text} (${i})`);
|
|
981
|
+
const computeFirstOne = options.computeFirstOne ?? false;
|
|
982
|
+
let i = options.start ?? 1;
|
|
983
|
+
let newText = computeFirstOne ? compute(text, i) : text;
|
|
984
|
+
while (texts.includes(newText)) {
|
|
985
|
+
newText = compute(text, i++);
|
|
986
|
+
}
|
|
987
|
+
return newText;
|
|
988
|
+
}
|
|
978
989
|
|
|
979
990
|
const RBA_REGEX = /rgba?\(|\s+|\)/gi;
|
|
980
991
|
const HEX_MATCH = /^#([A-F\d]{2}){3,4}$/;
|
|
@@ -6028,10 +6039,10 @@
|
|
|
6028
6039
|
}
|
|
6029
6040
|
}
|
|
6030
6041
|
/**
|
|
6031
|
-
*
|
|
6042
|
+
* Duplicate a range. If the range is on the sheetIdFrom, the range will target
|
|
6032
6043
|
* sheetIdTo.
|
|
6033
6044
|
*/
|
|
6034
|
-
function
|
|
6045
|
+
function duplicateRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, range) {
|
|
6035
6046
|
const sheetId = range.sheetId === sheetIdFrom ? sheetIdTo : range.sheetId;
|
|
6036
6047
|
return range.clone({ sheetId });
|
|
6037
6048
|
}
|
|
@@ -9464,6 +9475,150 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9464
9475
|
}
|
|
9465
9476
|
}
|
|
9466
9477
|
|
|
9478
|
+
/**
|
|
9479
|
+
* This file is largely inspired by owl 1.
|
|
9480
|
+
* `css` tag has been removed from owl 2 without workaround to manage css.
|
|
9481
|
+
* So, the solution was to import the behavior of owl 1 directly in our
|
|
9482
|
+
* codebase, with one difference: the css is added to the sheet as soon as the
|
|
9483
|
+
* css tag is executed. In owl 1, the css was added as soon as a Component was
|
|
9484
|
+
* created for the first time.
|
|
9485
|
+
*/
|
|
9486
|
+
const STYLESHEETS = {};
|
|
9487
|
+
let nextId = 0;
|
|
9488
|
+
/**
|
|
9489
|
+
* CSS tag helper for defining inline stylesheets. With this, one can simply define
|
|
9490
|
+
* an inline stylesheet with just the following code:
|
|
9491
|
+
* ```js
|
|
9492
|
+
* css`.component-a { color: red; }`;
|
|
9493
|
+
* ```
|
|
9494
|
+
*/
|
|
9495
|
+
function css(strings, ...args) {
|
|
9496
|
+
const name = `__sheet__${nextId++}`;
|
|
9497
|
+
const value = String.raw(strings, ...args);
|
|
9498
|
+
registerSheet(name, value);
|
|
9499
|
+
activateSheet(name);
|
|
9500
|
+
return name;
|
|
9501
|
+
}
|
|
9502
|
+
function processSheet(str) {
|
|
9503
|
+
const tokens = str.split(/(\{|\}|;)/).map((s) => s.trim());
|
|
9504
|
+
const selectorStack = [];
|
|
9505
|
+
const parts = [];
|
|
9506
|
+
let rules = [];
|
|
9507
|
+
function generateSelector(stackIndex, parentSelector) {
|
|
9508
|
+
const parts = [];
|
|
9509
|
+
for (const selector of selectorStack[stackIndex]) {
|
|
9510
|
+
let part = (parentSelector && parentSelector + " " + selector) || selector;
|
|
9511
|
+
if (part.includes("&")) {
|
|
9512
|
+
part = selector.replace(/&/g, parentSelector || "");
|
|
9513
|
+
}
|
|
9514
|
+
if (stackIndex < selectorStack.length - 1) {
|
|
9515
|
+
part = generateSelector(stackIndex + 1, part);
|
|
9516
|
+
}
|
|
9517
|
+
parts.push(part);
|
|
9518
|
+
}
|
|
9519
|
+
return parts.join(", ");
|
|
9520
|
+
}
|
|
9521
|
+
function generateRules() {
|
|
9522
|
+
if (rules.length) {
|
|
9523
|
+
parts.push(generateSelector(0) + " {");
|
|
9524
|
+
parts.push(...rules);
|
|
9525
|
+
parts.push("}");
|
|
9526
|
+
rules = [];
|
|
9527
|
+
}
|
|
9528
|
+
}
|
|
9529
|
+
while (tokens.length) {
|
|
9530
|
+
let token = tokens.shift();
|
|
9531
|
+
if (token === "}") {
|
|
9532
|
+
generateRules();
|
|
9533
|
+
selectorStack.pop();
|
|
9534
|
+
}
|
|
9535
|
+
else {
|
|
9536
|
+
if (tokens[0] === "{") {
|
|
9537
|
+
generateRules();
|
|
9538
|
+
selectorStack.push(token.split(/\s*,\s*/));
|
|
9539
|
+
tokens.shift();
|
|
9540
|
+
}
|
|
9541
|
+
if (tokens[0] === ";") {
|
|
9542
|
+
rules.push(" " + token + ";");
|
|
9543
|
+
}
|
|
9544
|
+
}
|
|
9545
|
+
}
|
|
9546
|
+
return parts.join("\n");
|
|
9547
|
+
}
|
|
9548
|
+
function registerSheet(id, css) {
|
|
9549
|
+
const sheet = document.createElement("style");
|
|
9550
|
+
sheet.textContent = processSheet(css);
|
|
9551
|
+
STYLESHEETS[id] = sheet;
|
|
9552
|
+
}
|
|
9553
|
+
function activateSheet(id) {
|
|
9554
|
+
const sheet = STYLESHEETS[id];
|
|
9555
|
+
sheet.setAttribute("component", id);
|
|
9556
|
+
document.head.appendChild(sheet);
|
|
9557
|
+
}
|
|
9558
|
+
function getTextDecoration({ strikethrough, underline, }) {
|
|
9559
|
+
if (!strikethrough && !underline) {
|
|
9560
|
+
return "none";
|
|
9561
|
+
}
|
|
9562
|
+
return `${strikethrough ? "line-through" : ""} ${underline ? "underline" : ""}`;
|
|
9563
|
+
}
|
|
9564
|
+
/**
|
|
9565
|
+
* Convert the cell style to CSS properties.
|
|
9566
|
+
*/
|
|
9567
|
+
function cellStyleToCss(style) {
|
|
9568
|
+
const attributes = cellTextStyleToCss(style);
|
|
9569
|
+
if (!style)
|
|
9570
|
+
return attributes;
|
|
9571
|
+
if (style.fillColor) {
|
|
9572
|
+
attributes["background"] = style.fillColor;
|
|
9573
|
+
}
|
|
9574
|
+
return attributes;
|
|
9575
|
+
}
|
|
9576
|
+
/**
|
|
9577
|
+
* Convert the cell text style to CSS properties.
|
|
9578
|
+
*/
|
|
9579
|
+
function cellTextStyleToCss(style) {
|
|
9580
|
+
const attributes = {};
|
|
9581
|
+
if (!style)
|
|
9582
|
+
return attributes;
|
|
9583
|
+
if (style.bold) {
|
|
9584
|
+
attributes["font-weight"] = "bold";
|
|
9585
|
+
}
|
|
9586
|
+
if (style.italic) {
|
|
9587
|
+
attributes["font-style"] = "italic";
|
|
9588
|
+
}
|
|
9589
|
+
if (style.strikethrough || style.underline) {
|
|
9590
|
+
let decoration = style.strikethrough ? "line-through" : "";
|
|
9591
|
+
decoration = style.underline ? decoration + " underline" : decoration;
|
|
9592
|
+
attributes["text-decoration"] = decoration;
|
|
9593
|
+
}
|
|
9594
|
+
if (style.textColor) {
|
|
9595
|
+
attributes["color"] = style.textColor;
|
|
9596
|
+
}
|
|
9597
|
+
return attributes;
|
|
9598
|
+
}
|
|
9599
|
+
/**
|
|
9600
|
+
* Transform CSS properties into a CSS string.
|
|
9601
|
+
*/
|
|
9602
|
+
function cssPropertiesToCss(attributes) {
|
|
9603
|
+
let styleStr = "";
|
|
9604
|
+
for (const attName in attributes) {
|
|
9605
|
+
if (!attributes[attName]) {
|
|
9606
|
+
continue;
|
|
9607
|
+
}
|
|
9608
|
+
styleStr += `${attName}:${attributes[attName]}; `;
|
|
9609
|
+
}
|
|
9610
|
+
return styleStr;
|
|
9611
|
+
}
|
|
9612
|
+
function getElementMargins(el) {
|
|
9613
|
+
const style = window.getComputedStyle(el);
|
|
9614
|
+
return {
|
|
9615
|
+
top: parseInt(style.marginTop, 10) || 0,
|
|
9616
|
+
bottom: parseInt(style.marginBottom, 10) || 0,
|
|
9617
|
+
left: parseInt(style.marginLeft, 10) || 0,
|
|
9618
|
+
right: parseInt(style.marginRight, 10) || 0,
|
|
9619
|
+
};
|
|
9620
|
+
}
|
|
9621
|
+
|
|
9467
9622
|
const TREND_LINE_XAXIS_ID = "x1";
|
|
9468
9623
|
/**
|
|
9469
9624
|
* This file contains helpers that are common to different charts (mainly
|
|
@@ -9516,25 +9671,25 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9516
9671
|
};
|
|
9517
9672
|
}
|
|
9518
9673
|
/**
|
|
9519
|
-
*
|
|
9674
|
+
* Duplicate the dataSets. All ranges on sheetIdFrom are adapted to target
|
|
9520
9675
|
* sheetIdTo.
|
|
9521
9676
|
*/
|
|
9522
|
-
function
|
|
9677
|
+
function duplicateDataSetsInDuplicatedSheet(sheetIdFrom, sheetIdTo, dataSets) {
|
|
9523
9678
|
return dataSets.map((ds) => {
|
|
9524
9679
|
return {
|
|
9525
|
-
dataRange:
|
|
9680
|
+
dataRange: duplicateRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, ds.dataRange),
|
|
9526
9681
|
labelCell: ds.labelCell
|
|
9527
|
-
?
|
|
9682
|
+
? duplicateRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, ds.labelCell)
|
|
9528
9683
|
: undefined,
|
|
9529
9684
|
};
|
|
9530
9685
|
});
|
|
9531
9686
|
}
|
|
9532
9687
|
/**
|
|
9533
|
-
*
|
|
9688
|
+
* Duplicate a range. If the range is on the sheetIdFrom, the range will target
|
|
9534
9689
|
* sheetIdTo.
|
|
9535
9690
|
*/
|
|
9536
|
-
function
|
|
9537
|
-
return range ?
|
|
9691
|
+
function duplicateLabelRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, range) {
|
|
9692
|
+
return range ? duplicateRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, range) : undefined;
|
|
9538
9693
|
}
|
|
9539
9694
|
/**
|
|
9540
9695
|
* Adapt a single range of a chart
|
|
@@ -9787,10 +9942,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9787
9942
|
if (isNaN(value))
|
|
9788
9943
|
return value;
|
|
9789
9944
|
const { locale, format } = localeFormat;
|
|
9790
|
-
|
|
9945
|
+
const formattedValue = formatValue(value, {
|
|
9791
9946
|
locale,
|
|
9792
9947
|
format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
|
|
9793
9948
|
});
|
|
9949
|
+
return truncateLabel(formattedValue);
|
|
9794
9950
|
};
|
|
9795
9951
|
}
|
|
9796
9952
|
const CHART_AXIS_CHOICES = [
|
|
@@ -9805,6 +9961,15 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9805
9961
|
}
|
|
9806
9962
|
return pieColors;
|
|
9807
9963
|
}
|
|
9964
|
+
function truncateLabel(label) {
|
|
9965
|
+
if (!label) {
|
|
9966
|
+
return "";
|
|
9967
|
+
}
|
|
9968
|
+
if (label.length > MAX_CHAR_LABEL) {
|
|
9969
|
+
return label.substring(0, MAX_CHAR_LABEL) + "…";
|
|
9970
|
+
}
|
|
9971
|
+
return label;
|
|
9972
|
+
}
|
|
9808
9973
|
|
|
9809
9974
|
/** This is a chartJS plugin that will draw the values of each data next to the point/bar/pie slice */
|
|
9810
9975
|
const chartShowValuesPlugin = {
|
|
@@ -10000,6 +10165,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10000
10165
|
|
|
10001
10166
|
window.Chart?.register(waterfallLinesPlugin);
|
|
10002
10167
|
window.Chart?.register(chartShowValuesPlugin);
|
|
10168
|
+
css /* scss */ `
|
|
10169
|
+
.o-spreadsheet {
|
|
10170
|
+
.o-chart-custom-tooltip {
|
|
10171
|
+
font-size: 12px;
|
|
10172
|
+
background-color: #fff;
|
|
10173
|
+
z-index: ${ComponentsImportance.FigureTooltip};
|
|
10174
|
+
table td span {
|
|
10175
|
+
box-sizing: border-box;
|
|
10176
|
+
}
|
|
10177
|
+
}
|
|
10178
|
+
}
|
|
10179
|
+
`;
|
|
10003
10180
|
class ChartJsComponent extends owl.Component {
|
|
10004
10181
|
static template = "o-spreadsheet-ChartJsComponent";
|
|
10005
10182
|
static props = {
|
|
@@ -10238,11 +10415,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10238
10415
|
keyValue: keyValueZone ? zoneToXc(keyValueZone) : undefined,
|
|
10239
10416
|
};
|
|
10240
10417
|
}
|
|
10241
|
-
|
|
10242
|
-
const baseline =
|
|
10243
|
-
const keyValue =
|
|
10244
|
-
const definition = this.getDefinitionWithSpecificRanges(baseline, keyValue,
|
|
10245
|
-
return new ScorecardChart(definition,
|
|
10418
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
10419
|
+
const baseline = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.baseline);
|
|
10420
|
+
const keyValue = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.keyValue);
|
|
10421
|
+
const definition = this.getDefinitionWithSpecificRanges(baseline, keyValue, newSheetId);
|
|
10422
|
+
return new ScorecardChart(definition, newSheetId, this.getters);
|
|
10246
10423
|
}
|
|
10247
10424
|
copyInSheetId(sheetId) {
|
|
10248
10425
|
const definition = this.getDefinitionWithSpecificRanges(this.baseline, this.keyValue, sheetId);
|
|
@@ -22569,15 +22746,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22569
22746
|
},
|
|
22570
22747
|
animation: false,
|
|
22571
22748
|
};
|
|
22572
|
-
function truncateLabel(label) {
|
|
22573
|
-
if (!label) {
|
|
22574
|
-
return "";
|
|
22575
|
-
}
|
|
22576
|
-
if (label.length > MAX_CHAR_LABEL) {
|
|
22577
|
-
return label.substring(0, MAX_CHAR_LABEL) + "…";
|
|
22578
|
-
}
|
|
22579
|
-
return label;
|
|
22580
|
-
}
|
|
22581
22749
|
function chartToImage(runtime, figure, type) {
|
|
22582
22750
|
// wrap the canvas in a div with a fixed size because chart.js would
|
|
22583
22751
|
// fill the whole page otherwise
|
|
@@ -22899,150 +23067,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22899
23067
|
*/
|
|
22900
23068
|
const iconsOnCellRegistry = new Registry();
|
|
22901
23069
|
|
|
22902
|
-
/**
|
|
22903
|
-
* This file is largely inspired by owl 1.
|
|
22904
|
-
* `css` tag has been removed from owl 2 without workaround to manage css.
|
|
22905
|
-
* So, the solution was to import the behavior of owl 1 directly in our
|
|
22906
|
-
* codebase, with one difference: the css is added to the sheet as soon as the
|
|
22907
|
-
* css tag is executed. In owl 1, the css was added as soon as a Component was
|
|
22908
|
-
* created for the first time.
|
|
22909
|
-
*/
|
|
22910
|
-
const STYLESHEETS = {};
|
|
22911
|
-
let nextId = 0;
|
|
22912
|
-
/**
|
|
22913
|
-
* CSS tag helper for defining inline stylesheets. With this, one can simply define
|
|
22914
|
-
* an inline stylesheet with just the following code:
|
|
22915
|
-
* ```js
|
|
22916
|
-
* css`.component-a { color: red; }`;
|
|
22917
|
-
* ```
|
|
22918
|
-
*/
|
|
22919
|
-
function css(strings, ...args) {
|
|
22920
|
-
const name = `__sheet__${nextId++}`;
|
|
22921
|
-
const value = String.raw(strings, ...args);
|
|
22922
|
-
registerSheet(name, value);
|
|
22923
|
-
activateSheet(name);
|
|
22924
|
-
return name;
|
|
22925
|
-
}
|
|
22926
|
-
function processSheet(str) {
|
|
22927
|
-
const tokens = str.split(/(\{|\}|;)/).map((s) => s.trim());
|
|
22928
|
-
const selectorStack = [];
|
|
22929
|
-
const parts = [];
|
|
22930
|
-
let rules = [];
|
|
22931
|
-
function generateSelector(stackIndex, parentSelector) {
|
|
22932
|
-
const parts = [];
|
|
22933
|
-
for (const selector of selectorStack[stackIndex]) {
|
|
22934
|
-
let part = (parentSelector && parentSelector + " " + selector) || selector;
|
|
22935
|
-
if (part.includes("&")) {
|
|
22936
|
-
part = selector.replace(/&/g, parentSelector || "");
|
|
22937
|
-
}
|
|
22938
|
-
if (stackIndex < selectorStack.length - 1) {
|
|
22939
|
-
part = generateSelector(stackIndex + 1, part);
|
|
22940
|
-
}
|
|
22941
|
-
parts.push(part);
|
|
22942
|
-
}
|
|
22943
|
-
return parts.join(", ");
|
|
22944
|
-
}
|
|
22945
|
-
function generateRules() {
|
|
22946
|
-
if (rules.length) {
|
|
22947
|
-
parts.push(generateSelector(0) + " {");
|
|
22948
|
-
parts.push(...rules);
|
|
22949
|
-
parts.push("}");
|
|
22950
|
-
rules = [];
|
|
22951
|
-
}
|
|
22952
|
-
}
|
|
22953
|
-
while (tokens.length) {
|
|
22954
|
-
let token = tokens.shift();
|
|
22955
|
-
if (token === "}") {
|
|
22956
|
-
generateRules();
|
|
22957
|
-
selectorStack.pop();
|
|
22958
|
-
}
|
|
22959
|
-
else {
|
|
22960
|
-
if (tokens[0] === "{") {
|
|
22961
|
-
generateRules();
|
|
22962
|
-
selectorStack.push(token.split(/\s*,\s*/));
|
|
22963
|
-
tokens.shift();
|
|
22964
|
-
}
|
|
22965
|
-
if (tokens[0] === ";") {
|
|
22966
|
-
rules.push(" " + token + ";");
|
|
22967
|
-
}
|
|
22968
|
-
}
|
|
22969
|
-
}
|
|
22970
|
-
return parts.join("\n");
|
|
22971
|
-
}
|
|
22972
|
-
function registerSheet(id, css) {
|
|
22973
|
-
const sheet = document.createElement("style");
|
|
22974
|
-
sheet.textContent = processSheet(css);
|
|
22975
|
-
STYLESHEETS[id] = sheet;
|
|
22976
|
-
}
|
|
22977
|
-
function activateSheet(id) {
|
|
22978
|
-
const sheet = STYLESHEETS[id];
|
|
22979
|
-
sheet.setAttribute("component", id);
|
|
22980
|
-
document.head.appendChild(sheet);
|
|
22981
|
-
}
|
|
22982
|
-
function getTextDecoration({ strikethrough, underline, }) {
|
|
22983
|
-
if (!strikethrough && !underline) {
|
|
22984
|
-
return "none";
|
|
22985
|
-
}
|
|
22986
|
-
return `${strikethrough ? "line-through" : ""} ${underline ? "underline" : ""}`;
|
|
22987
|
-
}
|
|
22988
|
-
/**
|
|
22989
|
-
* Convert the cell style to CSS properties.
|
|
22990
|
-
*/
|
|
22991
|
-
function cellStyleToCss(style) {
|
|
22992
|
-
const attributes = cellTextStyleToCss(style);
|
|
22993
|
-
if (!style)
|
|
22994
|
-
return attributes;
|
|
22995
|
-
if (style.fillColor) {
|
|
22996
|
-
attributes["background"] = style.fillColor;
|
|
22997
|
-
}
|
|
22998
|
-
return attributes;
|
|
22999
|
-
}
|
|
23000
|
-
/**
|
|
23001
|
-
* Convert the cell text style to CSS properties.
|
|
23002
|
-
*/
|
|
23003
|
-
function cellTextStyleToCss(style) {
|
|
23004
|
-
const attributes = {};
|
|
23005
|
-
if (!style)
|
|
23006
|
-
return attributes;
|
|
23007
|
-
if (style.bold) {
|
|
23008
|
-
attributes["font-weight"] = "bold";
|
|
23009
|
-
}
|
|
23010
|
-
if (style.italic) {
|
|
23011
|
-
attributes["font-style"] = "italic";
|
|
23012
|
-
}
|
|
23013
|
-
if (style.strikethrough || style.underline) {
|
|
23014
|
-
let decoration = style.strikethrough ? "line-through" : "";
|
|
23015
|
-
decoration = style.underline ? decoration + " underline" : decoration;
|
|
23016
|
-
attributes["text-decoration"] = decoration;
|
|
23017
|
-
}
|
|
23018
|
-
if (style.textColor) {
|
|
23019
|
-
attributes["color"] = style.textColor;
|
|
23020
|
-
}
|
|
23021
|
-
return attributes;
|
|
23022
|
-
}
|
|
23023
|
-
/**
|
|
23024
|
-
* Transform CSS properties into a CSS string.
|
|
23025
|
-
*/
|
|
23026
|
-
function cssPropertiesToCss(attributes) {
|
|
23027
|
-
let styleStr = "";
|
|
23028
|
-
for (const attName in attributes) {
|
|
23029
|
-
if (!attributes[attName]) {
|
|
23030
|
-
continue;
|
|
23031
|
-
}
|
|
23032
|
-
styleStr += `${attName}:${attributes[attName]}; `;
|
|
23033
|
-
}
|
|
23034
|
-
return styleStr;
|
|
23035
|
-
}
|
|
23036
|
-
function getElementMargins(el) {
|
|
23037
|
-
const style = window.getComputedStyle(el);
|
|
23038
|
-
return {
|
|
23039
|
-
top: parseInt(style.marginTop, 10) || 0,
|
|
23040
|
-
bottom: parseInt(style.marginBottom, 10) || 0,
|
|
23041
|
-
left: parseInt(style.marginLeft, 10) || 0,
|
|
23042
|
-
right: parseInt(style.marginRight, 10) || 0,
|
|
23043
|
-
};
|
|
23044
|
-
}
|
|
23045
|
-
|
|
23046
23070
|
css /* scss */ `
|
|
23047
23071
|
.o-spreadsheet {
|
|
23048
23072
|
.o-icon {
|
|
@@ -27162,12 +27186,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27162
27186
|
}
|
|
27163
27187
|
const oldName = sheet.name;
|
|
27164
27188
|
const escapedName = sanitizeSheetName(oldName, "_");
|
|
27165
|
-
|
|
27166
|
-
|
|
27167
|
-
|
|
27168
|
-
newName = `${escapedName}${i}`;
|
|
27169
|
-
i++;
|
|
27170
|
-
}
|
|
27189
|
+
const newName = getUniqueText(escapedName, namesTaken, {
|
|
27190
|
+
compute: (name, i) => `${name}${i}`,
|
|
27191
|
+
});
|
|
27171
27192
|
sheet.name = newName;
|
|
27172
27193
|
namesTaken.push(newName);
|
|
27173
27194
|
const replaceName = (str) => {
|
|
@@ -28700,7 +28721,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28700
28721
|
: undefined;
|
|
28701
28722
|
label =
|
|
28702
28723
|
cell && labelRange
|
|
28703
|
-
?
|
|
28724
|
+
? cell.formattedValue
|
|
28704
28725
|
: (label = `${ChartTerms.Series} ${parseInt(dsIndex) + 1}`);
|
|
28705
28726
|
}
|
|
28706
28727
|
else {
|
|
@@ -28790,7 +28811,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28790
28811
|
}
|
|
28791
28812
|
return {
|
|
28792
28813
|
datasets: [dataset],
|
|
28793
|
-
labels: labelsWithSubTotals
|
|
28814
|
+
labels: labelsWithSubTotals,
|
|
28794
28815
|
};
|
|
28795
28816
|
}
|
|
28796
28817
|
function getLineChartDatasets(definition, args) {
|
|
@@ -29039,7 +29060,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29039
29060
|
generateLabels: (c) =>
|
|
29040
29061
|
//@ts-ignore
|
|
29041
29062
|
c.data.labels.map((label, index) => ({
|
|
29042
|
-
text: label,
|
|
29063
|
+
text: truncateLabel(String(label)),
|
|
29043
29064
|
strokeStyle: colors[index],
|
|
29044
29065
|
fillStyle: colors[index],
|
|
29045
29066
|
pointStyle: "rect",
|
|
@@ -29170,7 +29191,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29170
29191
|
generateLabels: (chart) => chart.data.datasets.map((dataset, index) => {
|
|
29171
29192
|
if (dataset["xAxisID"] === TREND_LINE_XAXIS_ID) {
|
|
29172
29193
|
return {
|
|
29173
|
-
text: dataset.label
|
|
29194
|
+
text: truncateLabel(dataset.label),
|
|
29174
29195
|
fontColor,
|
|
29175
29196
|
strokeStyle: dataset.borderColor,
|
|
29176
29197
|
hidden: !chart.isDatasetVisible(index),
|
|
@@ -29180,7 +29201,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29180
29201
|
};
|
|
29181
29202
|
}
|
|
29182
29203
|
return {
|
|
29183
|
-
text: dataset.label
|
|
29204
|
+
text: truncateLabel(dataset.label),
|
|
29184
29205
|
fontColor,
|
|
29185
29206
|
strokeStyle: dataset.borderColor,
|
|
29186
29207
|
fillStyle: dataset.backgroundColor,
|
|
@@ -29327,7 +29348,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29327
29348
|
callback: formatTickValue({ format: axisFormats?.r, locale }),
|
|
29328
29349
|
backdropColor: definition.background || "#FFFFFF",
|
|
29329
29350
|
},
|
|
29330
|
-
pointLabels: {
|
|
29351
|
+
pointLabels: {
|
|
29352
|
+
color: chartFontColor(definition.background),
|
|
29353
|
+
callback: truncateLabel,
|
|
29354
|
+
},
|
|
29331
29355
|
suggestedMin: minValue < 0 ? minValue - 1 : 0,
|
|
29332
29356
|
},
|
|
29333
29357
|
};
|
|
@@ -29424,6 +29448,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29424
29448
|
ticks: {
|
|
29425
29449
|
padding: 5,
|
|
29426
29450
|
color: fontColor,
|
|
29451
|
+
callback: function (tickValue) {
|
|
29452
|
+
// Category axis callback's internal tick value is the index of the label
|
|
29453
|
+
// https://www.chartjs.org/docs/latest/axes/labelling.html#creating-custom-tick-formats
|
|
29454
|
+
return truncateLabel(this.getLabelForValue(tickValue));
|
|
29455
|
+
},
|
|
29427
29456
|
},
|
|
29428
29457
|
grid: {
|
|
29429
29458
|
display: false,
|
|
@@ -29503,8 +29532,70 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29503
29532
|
};
|
|
29504
29533
|
}
|
|
29505
29534
|
|
|
29535
|
+
/**
|
|
29536
|
+
* Custom tooltip for the charts. Mostly copied from Odoo's custom tooltip, with some slight changes to make it work
|
|
29537
|
+
* with o-spreadsheet chart data and CSS.
|
|
29538
|
+
*
|
|
29539
|
+
* https://github.com/odoo/odoo/blob/18.0/addons/web/static/src/views/graph/graph_renderer.xml
|
|
29540
|
+
*/
|
|
29541
|
+
const templates = /* xml */ `
|
|
29542
|
+
<templates>
|
|
29543
|
+
<t t-name="o-spreadsheet-CustomTooltip">
|
|
29544
|
+
<div
|
|
29545
|
+
class="o-chart-custom-tooltip border rounded px-2 py-1 pe-none mw-100 position-absolute text-nowrap shadow opacity-100">
|
|
29546
|
+
<table class="overflow-hidden m-0">
|
|
29547
|
+
<thead>
|
|
29548
|
+
<tr>
|
|
29549
|
+
<th class="o-tooltip-title align-baseline border-0 text-truncate" t-esc="title" t-attf-style="max-width: {{ labelsMaxWidth }}"/>
|
|
29550
|
+
</tr>
|
|
29551
|
+
</thead>
|
|
29552
|
+
<tbody>
|
|
29553
|
+
<tr t-foreach="tooltipItems" t-as="tooltipItem" t-key="tooltipItem_index">
|
|
29554
|
+
<td>
|
|
29555
|
+
<span
|
|
29556
|
+
class="badge ps-2 py-2 rounded-0 align-middle"
|
|
29557
|
+
t-attf-style="background-color: {{ tooltipItem.boxColor }}"
|
|
29558
|
+
> </span>
|
|
29559
|
+
<small
|
|
29560
|
+
t-if="tooltipItem.label"
|
|
29561
|
+
class="o-tooltip-label d-inline-block text-truncate align-middle smaller ms-2"
|
|
29562
|
+
t-esc="tooltipItem.label"
|
|
29563
|
+
t-attf-style="max-width: {{ labelsMaxWidth }}"
|
|
29564
|
+
/>
|
|
29565
|
+
</td>
|
|
29566
|
+
<td class="o-tooltip-value ps-2 fw-bolder text-end">
|
|
29567
|
+
<small class="smaller d-inline-block text-truncate align-middle" t-attf-style="max-width: {{ valuesMaxWidth }}">
|
|
29568
|
+
<t t-esc="tooltipItem.value"/>
|
|
29569
|
+
<t t-if="tooltipItem.percentage">
|
|
29570
|
+
(
|
|
29571
|
+
<t t-esc="tooltipItem.percentage"/>
|
|
29572
|
+
%)
|
|
29573
|
+
</t>
|
|
29574
|
+
</small>
|
|
29575
|
+
</td>
|
|
29576
|
+
</tr>
|
|
29577
|
+
</tbody>
|
|
29578
|
+
</table>
|
|
29579
|
+
</div>
|
|
29580
|
+
</t>
|
|
29581
|
+
</templates>
|
|
29582
|
+
`;
|
|
29583
|
+
const app = new owl.App(owl.Component, { templates, translateFn: _t });
|
|
29584
|
+
function renderToString(templateName, context = {}) {
|
|
29585
|
+
return render(templateName, context).innerHTML;
|
|
29586
|
+
}
|
|
29587
|
+
function render(templateName, context = {}) {
|
|
29588
|
+
const templateFn = app.getTemplate(templateName);
|
|
29589
|
+
const bdom = templateFn(context, {});
|
|
29590
|
+
const div = document.createElement("div");
|
|
29591
|
+
owl.blockDom.mount(bdom, div);
|
|
29592
|
+
return div;
|
|
29593
|
+
}
|
|
29594
|
+
|
|
29506
29595
|
function getBarChartTooltip(definition, args) {
|
|
29507
29596
|
return {
|
|
29597
|
+
enabled: false,
|
|
29598
|
+
external: customTooltipHandler,
|
|
29508
29599
|
callbacks: {
|
|
29509
29600
|
title: function (tooltipItems) {
|
|
29510
29601
|
return tooltipItems.some((item) => item.dataset.xAxisID !== TREND_LINE_XAXIS_ID)
|
|
@@ -29528,7 +29619,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29528
29619
|
function getLineChartTooltip(definition, args) {
|
|
29529
29620
|
const { axisType, locale, axisFormats } = args;
|
|
29530
29621
|
const labelFormat = axisFormats?.x;
|
|
29531
|
-
const tooltip = {
|
|
29622
|
+
const tooltip = {
|
|
29623
|
+
enabled: false,
|
|
29624
|
+
external: customTooltipHandler,
|
|
29625
|
+
callbacks: {},
|
|
29626
|
+
};
|
|
29532
29627
|
if (axisType === "linear") {
|
|
29533
29628
|
tooltip.callbacks.label = (tooltipItem) => {
|
|
29534
29629
|
const dataSetPoint = tooltipItem.parsed.y;
|
|
@@ -29567,6 +29662,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29567
29662
|
const { locale, axisFormats } = args;
|
|
29568
29663
|
const format = axisFormats?.y || axisFormats?.y1;
|
|
29569
29664
|
return {
|
|
29665
|
+
enabled: false,
|
|
29666
|
+
external: customTooltipHandler,
|
|
29570
29667
|
callbacks: {
|
|
29571
29668
|
title: function (tooltipItems) {
|
|
29572
29669
|
return tooltipItems[0].dataset.label;
|
|
@@ -29591,6 +29688,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29591
29688
|
const format = axisFormats?.y || axisFormats?.y1;
|
|
29592
29689
|
const dataSeriesLabels = dataSetsValues.map((dataSet) => dataSet.label);
|
|
29593
29690
|
return {
|
|
29691
|
+
enabled: false,
|
|
29692
|
+
external: customTooltipHandler,
|
|
29594
29693
|
callbacks: {
|
|
29595
29694
|
label: function (tooltipItem) {
|
|
29596
29695
|
const [lastValue, currentValue] = tooltipItem.raw;
|
|
@@ -29622,6 +29721,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29622
29721
|
function getRadarChartTooltip(definition, args) {
|
|
29623
29722
|
const { locale, axisFormats } = args;
|
|
29624
29723
|
return {
|
|
29724
|
+
enabled: false,
|
|
29725
|
+
external: customTooltipHandler,
|
|
29625
29726
|
callbacks: {
|
|
29626
29727
|
label: function (tooltipItem) {
|
|
29627
29728
|
const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
|
|
@@ -29660,6 +29761,48 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29660
29761
|
const percentage = (dataset[dataIndex] / total) * 100;
|
|
29661
29762
|
return percentage.toFixed(2);
|
|
29662
29763
|
}
|
|
29764
|
+
function customTooltipHandler({ chart, tooltip }) {
|
|
29765
|
+
chart.canvas.parentNode.querySelector("div.o-chart-custom-tooltip")?.remove();
|
|
29766
|
+
if (tooltip.opacity === 0 || tooltip.dataPoints.length === 0) {
|
|
29767
|
+
return;
|
|
29768
|
+
}
|
|
29769
|
+
const tooltipItems = tooltip.body.map((body, index) => {
|
|
29770
|
+
let [label, value] = body.lines[0].split(":").map((str) => str.trim());
|
|
29771
|
+
if (!value) {
|
|
29772
|
+
value = label;
|
|
29773
|
+
label = "";
|
|
29774
|
+
}
|
|
29775
|
+
const color = tooltip.labelColors[index].backgroundColor;
|
|
29776
|
+
return {
|
|
29777
|
+
label,
|
|
29778
|
+
value,
|
|
29779
|
+
boxColor: typeof color === "string" ? setColorAlpha(color, 1) : color,
|
|
29780
|
+
};
|
|
29781
|
+
});
|
|
29782
|
+
const innerHTML = renderToString("o-spreadsheet-CustomTooltip", {
|
|
29783
|
+
labelsMaxWidth: Math.floor(chart.canvas.clientWidth * 0.5) + "px",
|
|
29784
|
+
valuesMaxWidth: Math.floor(chart.canvas.clientWidth * 0.25) + "px",
|
|
29785
|
+
title: tooltip.title[0],
|
|
29786
|
+
tooltipItems,
|
|
29787
|
+
});
|
|
29788
|
+
const template = Object.assign(document.createElement("template"), { innerHTML });
|
|
29789
|
+
const newTooltipEl = template.content.firstChild;
|
|
29790
|
+
chart.canvas.parentNode?.appendChild(newTooltipEl);
|
|
29791
|
+
Object.assign(newTooltipEl.style, {
|
|
29792
|
+
left: getTooltipLeftPosition(chart, tooltip, newTooltipEl.clientWidth) + "px",
|
|
29793
|
+
top: Math.floor(tooltip.caretY - newTooltipEl.clientHeight / 2) + "px",
|
|
29794
|
+
});
|
|
29795
|
+
}
|
|
29796
|
+
/**
|
|
29797
|
+
* Get the left position for the tooltip, making sure it doesn't go out of the chart area.
|
|
29798
|
+
*/
|
|
29799
|
+
function getTooltipLeftPosition(chart, tooltip, tooltipWidth) {
|
|
29800
|
+
const x = tooltip.caretX;
|
|
29801
|
+
if (x + tooltipWidth > chart.chartArea.right) {
|
|
29802
|
+
return Math.max(0, x - tooltipWidth);
|
|
29803
|
+
}
|
|
29804
|
+
return x;
|
|
29805
|
+
}
|
|
29663
29806
|
|
|
29664
29807
|
var CHART_RUNTIME_HELPERS = /*#__PURE__*/Object.freeze({
|
|
29665
29808
|
__proto__: null,
|
|
@@ -29773,11 +29916,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29773
29916
|
: undefined,
|
|
29774
29917
|
};
|
|
29775
29918
|
}
|
|
29776
|
-
|
|
29777
|
-
const dataSets =
|
|
29778
|
-
const labelRange =
|
|
29779
|
-
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange,
|
|
29780
|
-
return new BarChart(definition,
|
|
29919
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
29920
|
+
const dataSets = duplicateDataSetsInDuplicatedSheet(this.sheetId, newSheetId, this.dataSets);
|
|
29921
|
+
const labelRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.labelRange);
|
|
29922
|
+
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange, newSheetId);
|
|
29923
|
+
return new BarChart(definition, newSheetId, this.getters);
|
|
29781
29924
|
}
|
|
29782
29925
|
copyInSheetId(sheetId) {
|
|
29783
29926
|
const definition = this.getDefinitionWithSpecificDataSets(this.dataSets, this.labelRange, sheetId);
|
|
@@ -29844,7 +29987,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29844
29987
|
const config = {
|
|
29845
29988
|
type: "bar",
|
|
29846
29989
|
data: {
|
|
29847
|
-
labels: chartData.labels
|
|
29990
|
+
labels: chartData.labels,
|
|
29848
29991
|
datasets: getBarChartDatasets(definition, chartData),
|
|
29849
29992
|
},
|
|
29850
29993
|
options: {
|
|
@@ -29980,11 +30123,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29980
30123
|
showValues: context.showValues,
|
|
29981
30124
|
};
|
|
29982
30125
|
}
|
|
29983
|
-
|
|
29984
|
-
const dataSets =
|
|
29985
|
-
const labelRange =
|
|
29986
|
-
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange,
|
|
29987
|
-
return new ComboChart(definition,
|
|
30126
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
30127
|
+
const dataSets = duplicateDataSetsInDuplicatedSheet(this.sheetId, newSheetId, this.dataSets);
|
|
30128
|
+
const labelRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.labelRange);
|
|
30129
|
+
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange, newSheetId);
|
|
30130
|
+
return new ComboChart(definition, newSheetId, this.getters);
|
|
29988
30131
|
}
|
|
29989
30132
|
copyInSheetId(sheetId) {
|
|
29990
30133
|
const definition = this.getDefinitionWithSpecificDataSets(this.dataSets, this.labelRange, sheetId);
|
|
@@ -29997,7 +30140,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29997
30140
|
const config = {
|
|
29998
30141
|
type: "bar",
|
|
29999
30142
|
data: {
|
|
30000
|
-
labels: chartData.labels
|
|
30143
|
+
labels: chartData.labels,
|
|
30001
30144
|
datasets: getComboChartDatasets(definition, chartData),
|
|
30002
30145
|
},
|
|
30003
30146
|
options: {
|
|
@@ -30131,10 +30274,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
30131
30274
|
},
|
|
30132
30275
|
};
|
|
30133
30276
|
}
|
|
30134
|
-
|
|
30135
|
-
const dataRange =
|
|
30136
|
-
const definition = this.getDefinitionWithSpecificRanges(dataRange,
|
|
30137
|
-
return new GaugeChart(definition,
|
|
30277
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
30278
|
+
const dataRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.dataRange);
|
|
30279
|
+
const definition = this.getDefinitionWithSpecificRanges(dataRange, newSheetId);
|
|
30280
|
+
return new GaugeChart(definition, newSheetId, this.getters);
|
|
30138
30281
|
}
|
|
30139
30282
|
copyInSheetId(sheetId) {
|
|
30140
30283
|
const definition = this.getDefinitionWithSpecificRanges(this.dataRange, sheetId);
|
|
@@ -30315,11 +30458,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
30315
30458
|
: undefined,
|
|
30316
30459
|
};
|
|
30317
30460
|
}
|
|
30318
|
-
|
|
30319
|
-
const dataSets =
|
|
30320
|
-
const labelRange =
|
|
30321
|
-
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange,
|
|
30322
|
-
return new GeoChart(definition,
|
|
30461
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
30462
|
+
const dataSets = duplicateDataSetsInDuplicatedSheet(this.sheetId, newSheetId, this.dataSets);
|
|
30463
|
+
const labelRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.labelRange);
|
|
30464
|
+
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange, newSheetId);
|
|
30465
|
+
return new GeoChart(definition, newSheetId, this.getters);
|
|
30323
30466
|
}
|
|
30324
30467
|
copyInSheetId(sheetId) {
|
|
30325
30468
|
const definition = this.getDefinitionWithSpecificDataSets(this.dataSets, this.labelRange, sheetId);
|
|
@@ -30512,11 +30655,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
30512
30655
|
verticalAxis: getDefinedAxis(definition),
|
|
30513
30656
|
};
|
|
30514
30657
|
}
|
|
30515
|
-
|
|
30516
|
-
const dataSets =
|
|
30517
|
-
const labelRange =
|
|
30518
|
-
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange,
|
|
30519
|
-
return new LineChart(definition,
|
|
30658
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
30659
|
+
const dataSets = duplicateDataSetsInDuplicatedSheet(this.sheetId, newSheetId, this.dataSets);
|
|
30660
|
+
const labelRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.labelRange);
|
|
30661
|
+
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange, newSheetId);
|
|
30662
|
+
return new LineChart(definition, newSheetId, this.getters);
|
|
30520
30663
|
}
|
|
30521
30664
|
copyInSheetId(sheetId) {
|
|
30522
30665
|
const definition = this.getDefinitionWithSpecificDataSets(this.dataSets, this.labelRange, sheetId);
|
|
@@ -30529,7 +30672,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
30529
30672
|
const config = {
|
|
30530
30673
|
type: "line",
|
|
30531
30674
|
data: {
|
|
30532
|
-
labels: chartData.
|
|
30675
|
+
labels: chartData.labels,
|
|
30533
30676
|
datasets: getLineChartDatasets(definition, chartData),
|
|
30534
30677
|
},
|
|
30535
30678
|
options: {
|
|
@@ -30623,11 +30766,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
30623
30766
|
showValues: this.showValues,
|
|
30624
30767
|
};
|
|
30625
30768
|
}
|
|
30626
|
-
|
|
30627
|
-
const dataSets =
|
|
30628
|
-
const labelRange =
|
|
30629
|
-
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange,
|
|
30630
|
-
return new PieChart(definition,
|
|
30769
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
30770
|
+
const dataSets = duplicateDataSetsInDuplicatedSheet(this.sheetId, newSheetId, this.dataSets);
|
|
30771
|
+
const labelRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.labelRange);
|
|
30772
|
+
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange, newSheetId);
|
|
30773
|
+
return new PieChart(definition, newSheetId, this.getters);
|
|
30631
30774
|
}
|
|
30632
30775
|
copyInSheetId(sheetId) {
|
|
30633
30776
|
const definition = this.getDefinitionWithSpecificDataSets(this.dataSets, this.labelRange, sheetId);
|
|
@@ -30664,7 +30807,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
30664
30807
|
const config = {
|
|
30665
30808
|
type: chart.isDoughnut ? "doughnut" : "pie",
|
|
30666
30809
|
data: {
|
|
30667
|
-
labels: chartData.labels
|
|
30810
|
+
labels: chartData.labels,
|
|
30668
30811
|
datasets: getPieChartDatasets(definition, chartData),
|
|
30669
30812
|
},
|
|
30670
30813
|
options: {
|
|
@@ -30744,11 +30887,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
30744
30887
|
: undefined,
|
|
30745
30888
|
};
|
|
30746
30889
|
}
|
|
30747
|
-
|
|
30748
|
-
const dataSets =
|
|
30749
|
-
const labelRange =
|
|
30750
|
-
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange,
|
|
30751
|
-
return new PyramidChart(definition,
|
|
30890
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
30891
|
+
const dataSets = duplicateDataSetsInDuplicatedSheet(this.sheetId, newSheetId, this.dataSets);
|
|
30892
|
+
const labelRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.labelRange);
|
|
30893
|
+
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange, newSheetId);
|
|
30894
|
+
return new PyramidChart(definition, newSheetId, this.getters);
|
|
30752
30895
|
}
|
|
30753
30896
|
copyInSheetId(sheetId) {
|
|
30754
30897
|
const definition = this.getDefinitionWithSpecificDataSets(this.dataSets, this.labelRange, sheetId);
|
|
@@ -30800,7 +30943,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
30800
30943
|
const config = {
|
|
30801
30944
|
type: "bar",
|
|
30802
30945
|
data: {
|
|
30803
|
-
labels: chartData.labels
|
|
30946
|
+
labels: chartData.labels,
|
|
30804
30947
|
datasets: getBarChartDatasets(definition, chartData),
|
|
30805
30948
|
},
|
|
30806
30949
|
options: {
|
|
@@ -30881,11 +31024,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
30881
31024
|
: undefined,
|
|
30882
31025
|
};
|
|
30883
31026
|
}
|
|
30884
|
-
|
|
30885
|
-
const dataSets =
|
|
30886
|
-
const labelRange =
|
|
30887
|
-
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange,
|
|
30888
|
-
return new RadarChart(definition,
|
|
31027
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
31028
|
+
const dataSets = duplicateDataSetsInDuplicatedSheet(this.sheetId, newSheetId, this.dataSets);
|
|
31029
|
+
const labelRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.labelRange);
|
|
31030
|
+
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange, newSheetId);
|
|
31031
|
+
return new RadarChart(definition, newSheetId, this.getters);
|
|
30889
31032
|
}
|
|
30890
31033
|
copyInSheetId(sheetId) {
|
|
30891
31034
|
const definition = this.getDefinitionWithSpecificDataSets(this.dataSets, this.labelRange, sheetId);
|
|
@@ -30950,7 +31093,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
30950
31093
|
const config = {
|
|
30951
31094
|
type: "radar",
|
|
30952
31095
|
data: {
|
|
30953
|
-
labels: chartData.labels
|
|
31096
|
+
labels: chartData.labels,
|
|
30954
31097
|
datasets: getRadarChartDatasets(definition, chartData),
|
|
30955
31098
|
},
|
|
30956
31099
|
options: {
|
|
@@ -31084,11 +31227,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
31084
31227
|
verticalAxis: getDefinedAxis(definition),
|
|
31085
31228
|
};
|
|
31086
31229
|
}
|
|
31087
|
-
|
|
31088
|
-
const dataSets =
|
|
31089
|
-
const labelRange =
|
|
31090
|
-
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange,
|
|
31091
|
-
return new ScatterChart(definition,
|
|
31230
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
31231
|
+
const dataSets = duplicateDataSetsInDuplicatedSheet(this.sheetId, newSheetId, this.dataSets);
|
|
31232
|
+
const labelRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.labelRange);
|
|
31233
|
+
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange, newSheetId);
|
|
31234
|
+
return new ScatterChart(definition, newSheetId, this.getters);
|
|
31092
31235
|
}
|
|
31093
31236
|
copyInSheetId(sheetId) {
|
|
31094
31237
|
const definition = this.getDefinitionWithSpecificDataSets(this.dataSets, this.labelRange, sheetId);
|
|
@@ -31103,7 +31246,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
31103
31246
|
// have less options than the line chart (it only works with linear labels)
|
|
31104
31247
|
type: "line",
|
|
31105
31248
|
data: {
|
|
31106
|
-
labels: chartData.
|
|
31249
|
+
labels: chartData.labels,
|
|
31107
31250
|
datasets: getScatterChartDatasets(definition, chartData),
|
|
31108
31251
|
},
|
|
31109
31252
|
options: {
|
|
@@ -31201,11 +31344,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
31201
31344
|
: undefined,
|
|
31202
31345
|
};
|
|
31203
31346
|
}
|
|
31204
|
-
|
|
31205
|
-
const dataSets =
|
|
31206
|
-
const labelRange =
|
|
31207
|
-
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange,
|
|
31208
|
-
return new WaterfallChart(definition,
|
|
31347
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
31348
|
+
const dataSets = duplicateDataSetsInDuplicatedSheet(this.sheetId, newSheetId, this.dataSets);
|
|
31349
|
+
const labelRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.labelRange);
|
|
31350
|
+
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange, newSheetId);
|
|
31351
|
+
return new WaterfallChart(definition, newSheetId, this.getters);
|
|
31209
31352
|
}
|
|
31210
31353
|
copyInSheetId(sheetId) {
|
|
31211
31354
|
const definition = this.getDefinitionWithSpecificDataSets(this.dataSets, this.labelRange, sheetId);
|
|
@@ -33632,8 +33775,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
33632
33775
|
chartToImage: chartToImage,
|
|
33633
33776
|
checkDataset: checkDataset,
|
|
33634
33777
|
checkLabelRange: checkLabelRange,
|
|
33635
|
-
copyDataSetsWithNewSheetId: copyDataSetsWithNewSheetId,
|
|
33636
|
-
copyLabelRangeWithNewSheetId: copyLabelRangeWithNewSheetId,
|
|
33637
33778
|
createBarChartRuntime: createBarChartRuntime,
|
|
33638
33779
|
createDataSets: createDataSets,
|
|
33639
33780
|
createGaugeChartRuntime: createGaugeChartRuntime,
|
|
@@ -33642,6 +33783,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
33642
33783
|
createScorecardChartRuntime: createScorecardChartRuntime,
|
|
33643
33784
|
createWaterfallChartRuntime: createWaterfallChartRuntime,
|
|
33644
33785
|
drawScoreChart: drawScoreChart,
|
|
33786
|
+
duplicateDataSetsInDuplicatedSheet: duplicateDataSetsInDuplicatedSheet,
|
|
33787
|
+
duplicateLabelRangeInDuplicatedSheet: duplicateLabelRangeInDuplicatedSheet,
|
|
33645
33788
|
formatChartDatasetValue: formatChartDatasetValue,
|
|
33646
33789
|
formatTickValue: formatTickValue,
|
|
33647
33790
|
getChartPositionAtCenterOfViewport: getChartPositionAtCenterOfViewport,
|
|
@@ -46074,12 +46217,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
46074
46217
|
* Take cares of double names
|
|
46075
46218
|
*/
|
|
46076
46219
|
findName(name, fields) {
|
|
46077
|
-
|
|
46078
|
-
|
|
46079
|
-
|
|
46080
|
-
|
|
46081
|
-
}
|
|
46082
|
-
return name;
|
|
46220
|
+
return getUniqueText(name, Object.keys(fields), {
|
|
46221
|
+
compute: (name, i) => `${name}${i}`,
|
|
46222
|
+
start: 2,
|
|
46223
|
+
});
|
|
46083
46224
|
}
|
|
46084
46225
|
extractDataEntriesFromRange(range) {
|
|
46085
46226
|
const dataEntries = [];
|
|
@@ -46321,13 +46462,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
46321
46462
|
}
|
|
46322
46463
|
}
|
|
46323
46464
|
isDynamicPivotInViewport() {
|
|
46324
|
-
const
|
|
46325
|
-
|
|
46326
|
-
|
|
46327
|
-
|
|
46328
|
-
if (isDynamicPivot) {
|
|
46329
|
-
return true;
|
|
46330
|
-
}
|
|
46465
|
+
for (const position of this.getters.getVisibleCellPositions()) {
|
|
46466
|
+
const isDynamicPivot = this.getters.isSpillPivotFormula(position);
|
|
46467
|
+
if (isDynamicPivot) {
|
|
46468
|
+
return true;
|
|
46331
46469
|
}
|
|
46332
46470
|
}
|
|
46333
46471
|
return false;
|
|
@@ -52321,15 +52459,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52321
52459
|
class BasePlugin {
|
|
52322
52460
|
static getters = [];
|
|
52323
52461
|
history;
|
|
52324
|
-
|
|
52325
|
-
canDispatch;
|
|
52326
|
-
constructor(stateObserver, dispatch, canDispatch) {
|
|
52462
|
+
constructor(stateObserver) {
|
|
52327
52463
|
this.history = Object.assign(Object.create(stateObserver), {
|
|
52328
52464
|
update: stateObserver.addChange.bind(stateObserver, this),
|
|
52329
52465
|
selectCell: () => { },
|
|
52330
52466
|
});
|
|
52331
|
-
this.dispatch = dispatch;
|
|
52332
|
-
this.canDispatch = canDispatch;
|
|
52333
52467
|
}
|
|
52334
52468
|
/**
|
|
52335
52469
|
* Export for excel should be available for all plugins, even for the UI.
|
|
@@ -52407,10 +52541,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52407
52541
|
*/
|
|
52408
52542
|
class CorePlugin extends BasePlugin {
|
|
52409
52543
|
getters;
|
|
52544
|
+
dispatch;
|
|
52545
|
+
canDispatch;
|
|
52410
52546
|
constructor({ getters, stateObserver, range, dispatch, canDispatch }) {
|
|
52411
|
-
super(stateObserver
|
|
52547
|
+
super(stateObserver);
|
|
52412
52548
|
range.addRangeProvider(this.adaptRanges.bind(this));
|
|
52413
52549
|
this.getters = getters;
|
|
52550
|
+
this.dispatch = dispatch;
|
|
52551
|
+
this.canDispatch = canDispatch;
|
|
52414
52552
|
}
|
|
52415
52553
|
// ---------------------------------------------------------------------------
|
|
52416
52554
|
// Import/Export
|
|
@@ -53647,7 +53785,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
53647
53785
|
if (fig.tag === "chart") {
|
|
53648
53786
|
const figureIdBase = fig.id.split(FIGURE_ID_SPLITTER).pop();
|
|
53649
53787
|
const duplicatedFigureId = `${cmd.sheetIdTo}${FIGURE_ID_SPLITTER}${figureIdBase}`;
|
|
53650
|
-
const chart = this.charts[fig.id]?.
|
|
53788
|
+
const chart = this.charts[fig.id]?.duplicateInDuplicatedSheet(cmd.sheetIdTo);
|
|
53651
53789
|
if (chart) {
|
|
53652
53790
|
this.dispatch("CREATE_CHART", {
|
|
53653
53791
|
id: duplicatedFigureId,
|
|
@@ -54291,7 +54429,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
54291
54429
|
case "DUPLICATE_SHEET": {
|
|
54292
54430
|
const rules = deepCopy(this.rules[cmd.sheetId]).map((rule) => ({
|
|
54293
54431
|
...rule,
|
|
54294
|
-
ranges: rule.ranges.map((range) =>
|
|
54432
|
+
ranges: rule.ranges.map((range) => duplicateRangeInDuplicatedSheet(cmd.sheetId, cmd.sheetIdTo, range)),
|
|
54295
54433
|
}));
|
|
54296
54434
|
this.history.update("rules", cmd.sheetIdTo, rules);
|
|
54297
54435
|
break;
|
|
@@ -56340,14 +56478,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
56340
56478
|
return dimension === "COL" ? this.getNumberCols(sheetId) : this.getNumberRows(sheetId);
|
|
56341
56479
|
}
|
|
56342
56480
|
getNextSheetName(baseName = "Sheet") {
|
|
56343
|
-
let i = 1;
|
|
56344
56481
|
const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
|
|
56345
|
-
|
|
56346
|
-
|
|
56347
|
-
|
|
56348
|
-
|
|
56349
|
-
}
|
|
56350
|
-
return name;
|
|
56482
|
+
return getUniqueText(baseName, names, {
|
|
56483
|
+
compute: (name, i) => `${name}${i}`,
|
|
56484
|
+
computeFirstOne: true,
|
|
56485
|
+
});
|
|
56351
56486
|
}
|
|
56352
56487
|
getSheetSize(sheetId) {
|
|
56353
56488
|
return {
|
|
@@ -56627,15 +56762,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
56627
56762
|
this.history.update("sheetIdsMapName", sheetIdsMapName);
|
|
56628
56763
|
}
|
|
56629
56764
|
getDuplicateSheetName(sheetName) {
|
|
56630
|
-
let i = 1;
|
|
56631
56765
|
const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
|
|
56632
56766
|
const baseName = _t("Copy of %s", sheetName);
|
|
56633
|
-
|
|
56634
|
-
while (names.includes(name)) {
|
|
56635
|
-
name = `${baseName} (${i})`;
|
|
56636
|
-
i++;
|
|
56637
|
-
}
|
|
56638
|
-
return name;
|
|
56767
|
+
return getUniqueText(baseName.toString(), names);
|
|
56639
56768
|
}
|
|
56640
56769
|
deleteSheet(sheet) {
|
|
56641
56770
|
const name = sheet.name;
|
|
@@ -58165,15 +58294,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
58165
58294
|
}
|
|
58166
58295
|
getNewCustomTableStyleName() {
|
|
58167
58296
|
let name = _t("Custom Table Style");
|
|
58168
|
-
const styleNames =
|
|
58169
|
-
|
|
58170
|
-
return name;
|
|
58171
|
-
}
|
|
58172
|
-
let i = 2;
|
|
58173
|
-
while (styleNames.has(`${name} ${i}`)) {
|
|
58174
|
-
i++;
|
|
58175
|
-
}
|
|
58176
|
-
return `${name} ${i}`;
|
|
58297
|
+
const styleNames = Object.values(this.styles).map((style) => style.displayName);
|
|
58298
|
+
return getUniqueText(name, styleNames, { compute: (name, i) => `${name} ${i}`, start: 2 });
|
|
58177
58299
|
}
|
|
58178
58300
|
isTableStyleEditable(styleId) {
|
|
58179
58301
|
return !TABLE_PRESETS[styleId];
|
|
@@ -58203,24 +58325,15 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
58203
58325
|
}
|
|
58204
58326
|
|
|
58205
58327
|
/**
|
|
58206
|
-
*
|
|
58207
|
-
* They
|
|
58328
|
+
* Core view plugins handle any data derived from core date (i.e. evaluation).
|
|
58329
|
+
* They cannot impact the model data (i.e. cannot dispatch commands).
|
|
58208
58330
|
*/
|
|
58209
|
-
class
|
|
58210
|
-
static layers = [];
|
|
58331
|
+
class CoreViewPlugin extends BasePlugin {
|
|
58211
58332
|
getters;
|
|
58212
|
-
|
|
58213
|
-
|
|
58214
|
-
constructor({ getters, stateObserver, dispatch, canDispatch, uiActions, selection, }) {
|
|
58215
|
-
super(stateObserver, dispatch, canDispatch);
|
|
58333
|
+
constructor({ getters, stateObserver }) {
|
|
58334
|
+
super(stateObserver);
|
|
58216
58335
|
this.getters = getters;
|
|
58217
|
-
this.ui = uiActions;
|
|
58218
|
-
this.selection = selection;
|
|
58219
58336
|
}
|
|
58220
|
-
// ---------------------------------------------------------------------------
|
|
58221
|
-
// Grid rendering
|
|
58222
|
-
// ---------------------------------------------------------------------------
|
|
58223
|
-
drawLayer(ctx, layer) { }
|
|
58224
58337
|
}
|
|
58225
58338
|
|
|
58226
58339
|
/**
|
|
@@ -59915,7 +60028,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
59915
60028
|
// as necessary in several iterations, where evaluated cells can trigger the evaluation
|
|
59916
60029
|
// of other cells depending on it, at the next iteration.
|
|
59917
60030
|
//#endregion
|
|
59918
|
-
class EvaluationPlugin extends
|
|
60031
|
+
class EvaluationPlugin extends CoreViewPlugin {
|
|
59919
60032
|
static getters = [
|
|
59920
60033
|
"evaluateFormula",
|
|
59921
60034
|
"evaluateFormulaResult",
|
|
@@ -60182,7 +60295,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
60182
60295
|
* This plugins aims to compute and keep to custom colors used in the
|
|
60183
60296
|
* current spreadsheet
|
|
60184
60297
|
*/
|
|
60185
|
-
class CustomColorsPlugin extends
|
|
60298
|
+
class CustomColorsPlugin extends CoreViewPlugin {
|
|
60186
60299
|
customColors = {};
|
|
60187
60300
|
shouldUpdateColors = true;
|
|
60188
60301
|
static getters = ["getCustomColors"];
|
|
@@ -60318,7 +60431,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
60318
60431
|
}
|
|
60319
60432
|
}
|
|
60320
60433
|
|
|
60321
|
-
class EvaluationChartPlugin extends
|
|
60434
|
+
class EvaluationChartPlugin extends CoreViewPlugin {
|
|
60322
60435
|
static getters = ["getChartRuntime", "getStyleOfSingleCellChart"];
|
|
60323
60436
|
charts = {};
|
|
60324
60437
|
createRuntimeChart = chartRuntimeFactory(this.getters);
|
|
@@ -60422,7 +60535,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
60422
60535
|
}
|
|
60423
60536
|
}
|
|
60424
60537
|
|
|
60425
|
-
class EvaluationConditionalFormatPlugin extends
|
|
60538
|
+
class EvaluationConditionalFormatPlugin extends CoreViewPlugin {
|
|
60426
60539
|
static getters = [
|
|
60427
60540
|
"getConditionalIcon",
|
|
60428
60541
|
"getCellConditionalFormatStyle",
|
|
@@ -60740,7 +60853,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
60740
60853
|
}
|
|
60741
60854
|
|
|
60742
60855
|
const VALID_RESULT = { isValid: true };
|
|
60743
|
-
class EvaluationDataValidationPlugin extends
|
|
60856
|
+
class EvaluationDataValidationPlugin extends CoreViewPlugin {
|
|
60744
60857
|
static getters = [
|
|
60745
60858
|
"getDataValidationInvalidCriterionValueMessage",
|
|
60746
60859
|
"getInvalidDataValidationMessage",
|
|
@@ -60871,7 +60984,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
60871
60984
|
}
|
|
60872
60985
|
}
|
|
60873
60986
|
|
|
60874
|
-
class DynamicTablesPlugin extends
|
|
60987
|
+
class DynamicTablesPlugin extends CoreViewPlugin {
|
|
60875
60988
|
static getters = [
|
|
60876
60989
|
"canCreateDynamicTableOnZones",
|
|
60877
60990
|
"doesZonesContainFilter",
|
|
@@ -61045,7 +61158,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
61045
61158
|
}
|
|
61046
61159
|
}
|
|
61047
61160
|
|
|
61048
|
-
class HeaderSizeUIPlugin extends
|
|
61161
|
+
class HeaderSizeUIPlugin extends CoreViewPlugin {
|
|
61049
61162
|
static getters = ["getRowSize", "getHeaderSize"];
|
|
61050
61163
|
tallestCellInRow = {};
|
|
61051
61164
|
ctx = document.createElement("canvas").getContext("2d");
|
|
@@ -61751,7 +61864,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
61751
61864
|
function isPivotCommand(cmd) {
|
|
61752
61865
|
return UNDO_REDO_PIVOT_COMMANDS.includes(cmd.type);
|
|
61753
61866
|
}
|
|
61754
|
-
class PivotUIPlugin extends
|
|
61867
|
+
class PivotUIPlugin extends CoreViewPlugin {
|
|
61755
61868
|
static getters = [
|
|
61756
61869
|
"getPivot",
|
|
61757
61870
|
"getFirstPivotFunction",
|
|
@@ -61955,13 +62068,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
61955
62068
|
}
|
|
61956
62069
|
generateNewCalculatedMeasureName(measures) {
|
|
61957
62070
|
const existingMeasures = measures.map((m) => m.fieldName);
|
|
61958
|
-
|
|
61959
|
-
|
|
61960
|
-
|
|
61961
|
-
i++;
|
|
61962
|
-
name = _t("Calculated measure %s", i);
|
|
61963
|
-
}
|
|
61964
|
-
return name;
|
|
62071
|
+
return getUniqueText(_t("Calculated measure 1"), existingMeasures, {
|
|
62072
|
+
compute: (name, i) => _t("Calculated measure %s", i),
|
|
62073
|
+
});
|
|
61965
62074
|
}
|
|
61966
62075
|
getPivot(pivotId) {
|
|
61967
62076
|
if (!this.getters.isExistingPivot(pivotId)) {
|
|
@@ -62015,6 +62124,31 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
62015
62124
|
}
|
|
62016
62125
|
}
|
|
62017
62126
|
|
|
62127
|
+
/**
|
|
62128
|
+
* UI plugins handle any transient data required to display a spreadsheet.
|
|
62129
|
+
* They can draw on the grid canvas.
|
|
62130
|
+
*/
|
|
62131
|
+
class UIPlugin extends BasePlugin {
|
|
62132
|
+
static layers = [];
|
|
62133
|
+
getters;
|
|
62134
|
+
ui;
|
|
62135
|
+
selection;
|
|
62136
|
+
dispatch;
|
|
62137
|
+
canDispatch;
|
|
62138
|
+
constructor({ getters, stateObserver, dispatch, canDispatch, uiActions, selection, }) {
|
|
62139
|
+
super(stateObserver);
|
|
62140
|
+
this.getters = getters;
|
|
62141
|
+
this.ui = uiActions;
|
|
62142
|
+
this.selection = selection;
|
|
62143
|
+
this.dispatch = dispatch;
|
|
62144
|
+
this.canDispatch = canDispatch;
|
|
62145
|
+
}
|
|
62146
|
+
// ---------------------------------------------------------------------------
|
|
62147
|
+
// Grid rendering
|
|
62148
|
+
// ---------------------------------------------------------------------------
|
|
62149
|
+
drawLayer(ctx, layer) { }
|
|
62150
|
+
}
|
|
62151
|
+
|
|
62018
62152
|
/**
|
|
62019
62153
|
* This plugin manage the autofill.
|
|
62020
62154
|
*
|
|
@@ -64130,15 +64264,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
64130
64264
|
}
|
|
64131
64265
|
}
|
|
64132
64266
|
getPivotDuplicateSheetName(pivotName) {
|
|
64133
|
-
let i = 1;
|
|
64134
64267
|
const names = this.getters.getSheetIds().map((id) => this.getters.getSheetName(id));
|
|
64135
64268
|
const sanitizedName = sanitizeSheetName(pivotName);
|
|
64136
|
-
|
|
64137
|
-
while (names.includes(name)) {
|
|
64138
|
-
name = `${sanitizedName} (${i})`;
|
|
64139
|
-
i++;
|
|
64140
|
-
}
|
|
64141
|
-
return name;
|
|
64269
|
+
return getUniqueText(sanitizedName, names);
|
|
64142
64270
|
}
|
|
64143
64271
|
insertPivotWithTable(sheetId, col, row, pivotId, table, mode) {
|
|
64144
64272
|
const { cols, rows, measures, fieldsType } = table;
|
|
@@ -66245,13 +66373,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
66245
66373
|
if (!colName) {
|
|
66246
66374
|
colName = `Column${colIndex}`;
|
|
66247
66375
|
}
|
|
66248
|
-
|
|
66249
|
-
|
|
66250
|
-
|
|
66251
|
-
|
|
66252
|
-
i++;
|
|
66253
|
-
}
|
|
66254
|
-
return currentColName;
|
|
66376
|
+
return getUniqueText(colName, usedColNames, {
|
|
66377
|
+
compute: (name, i) => colName + String(i),
|
|
66378
|
+
start: 2,
|
|
66379
|
+
});
|
|
66255
66380
|
}
|
|
66256
66381
|
}
|
|
66257
66382
|
|
|
@@ -68903,23 +69028,17 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68903
69028
|
const cells = [];
|
|
68904
69029
|
const getters = this.getters;
|
|
68905
69030
|
const sheetId = getters.getActiveSheetId();
|
|
68906
|
-
for (const
|
|
68907
|
-
|
|
68908
|
-
|
|
68909
|
-
|
|
68910
|
-
continue;
|
|
68911
|
-
}
|
|
68912
|
-
const action = this.getClickableAction(position);
|
|
68913
|
-
if (!action) {
|
|
68914
|
-
continue;
|
|
68915
|
-
}
|
|
68916
|
-
const zone = getters.expandZone(sheetId, positionToZone(position));
|
|
68917
|
-
cells.push({
|
|
68918
|
-
coordinates: getters.getVisibleRect(zone),
|
|
68919
|
-
position,
|
|
68920
|
-
action,
|
|
68921
|
-
});
|
|
69031
|
+
for (const position of this.getters.getVisibleCellPositions()) {
|
|
69032
|
+
const action = this.getClickableAction(position);
|
|
69033
|
+
if (!action) {
|
|
69034
|
+
continue;
|
|
68922
69035
|
}
|
|
69036
|
+
const zone = getters.expandZone(sheetId, positionToZone(position));
|
|
69037
|
+
cells.push({
|
|
69038
|
+
coordinates: getters.getVisibleRect(zone),
|
|
69039
|
+
position,
|
|
69040
|
+
action,
|
|
69041
|
+
});
|
|
68923
69042
|
}
|
|
68924
69043
|
return cells;
|
|
68925
69044
|
}
|
|
@@ -74170,14 +74289,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
74170
74289
|
*/
|
|
74171
74290
|
function fixLengthySheetNames(data) {
|
|
74172
74291
|
const nameMapping = {};
|
|
74173
|
-
const newNames =
|
|
74292
|
+
const newNames = [];
|
|
74174
74293
|
for (const sheet of data.sheets) {
|
|
74175
74294
|
let newName = sheet.name.slice(0, 31);
|
|
74176
|
-
|
|
74177
|
-
|
|
74178
|
-
|
|
74179
|
-
|
|
74180
|
-
newNames.add(newName);
|
|
74295
|
+
newName = getUniqueText(newName, newNames, {
|
|
74296
|
+
compute: (name, i) => name.slice(0, 31 - String(i).length) + i,
|
|
74297
|
+
});
|
|
74298
|
+
newNames.push(newName);
|
|
74181
74299
|
if (newName !== sheet.name) {
|
|
74182
74300
|
nameMapping[sheet.name] = newName;
|
|
74183
74301
|
sheet.name = newName;
|
|
@@ -74242,6 +74360,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
74242
74360
|
*/
|
|
74243
74361
|
config;
|
|
74244
74362
|
corePluginConfig;
|
|
74363
|
+
coreViewPluginConfig;
|
|
74245
74364
|
uiPluginConfig;
|
|
74246
74365
|
state;
|
|
74247
74366
|
selection;
|
|
@@ -74294,6 +74413,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
74294
74413
|
this.coreHandlers.push(this.range);
|
|
74295
74414
|
this.handlers.push(this.range);
|
|
74296
74415
|
this.corePluginConfig = this.setupCorePluginConfig();
|
|
74416
|
+
this.coreViewPluginConfig = this.setupCoreViewPluginConfig();
|
|
74297
74417
|
this.uiPluginConfig = this.setupUiPluginConfig();
|
|
74298
74418
|
// registering plugins
|
|
74299
74419
|
for (let Plugin of corePluginRegistry.getAll()) {
|
|
@@ -74302,7 +74422,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
74302
74422
|
Object.assign(this.getters, this.coreGetters);
|
|
74303
74423
|
this.session.loadInitialMessages(stateUpdateMessages);
|
|
74304
74424
|
for (let Plugin of coreViewsPluginRegistry.getAll()) {
|
|
74305
|
-
const plugin = this.
|
|
74425
|
+
const plugin = this.setupCoreViewPlugin(Plugin);
|
|
74306
74426
|
this.handlers.push(plugin);
|
|
74307
74427
|
this.uiHandlers.push(plugin);
|
|
74308
74428
|
this.coreHandlers.push(plugin);
|
|
@@ -74368,6 +74488,19 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
74368
74488
|
}
|
|
74369
74489
|
return plugin;
|
|
74370
74490
|
}
|
|
74491
|
+
setupCoreViewPlugin(Plugin) {
|
|
74492
|
+
const plugin = new Plugin(this.coreViewPluginConfig);
|
|
74493
|
+
for (let name of Plugin.getters) {
|
|
74494
|
+
if (!(name in plugin)) {
|
|
74495
|
+
throw new Error(`Invalid getter name: ${name} for plugin ${plugin.constructor}`);
|
|
74496
|
+
}
|
|
74497
|
+
if (name in this.getters) {
|
|
74498
|
+
throw new Error(`Getter "${name}" is already defined.`);
|
|
74499
|
+
}
|
|
74500
|
+
this.getters[name] = plugin[name].bind(plugin);
|
|
74501
|
+
}
|
|
74502
|
+
return plugin;
|
|
74503
|
+
}
|
|
74371
74504
|
/**
|
|
74372
74505
|
* Initialize and properly configure a plugin.
|
|
74373
74506
|
*
|
|
@@ -74469,6 +74602,20 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
74469
74602
|
external: this.config.external,
|
|
74470
74603
|
};
|
|
74471
74604
|
}
|
|
74605
|
+
setupCoreViewPluginConfig() {
|
|
74606
|
+
return {
|
|
74607
|
+
getters: this.getters,
|
|
74608
|
+
stateObserver: this.state,
|
|
74609
|
+
selection: this.selection,
|
|
74610
|
+
moveClient: this.session.move.bind(this.session),
|
|
74611
|
+
custom: this.config.custom,
|
|
74612
|
+
uiActions: this.config,
|
|
74613
|
+
session: this.session,
|
|
74614
|
+
defaultCurrency: this.config.defaultCurrency,
|
|
74615
|
+
customColors: this.config.customColors || [],
|
|
74616
|
+
external: this.config.external,
|
|
74617
|
+
};
|
|
74618
|
+
}
|
|
74472
74619
|
setupUiPluginConfig() {
|
|
74473
74620
|
return {
|
|
74474
74621
|
getters: this.getters,
|
|
@@ -74816,6 +74963,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
74816
74963
|
areDomainArgsFieldsValid,
|
|
74817
74964
|
splitReference,
|
|
74818
74965
|
sanitizeSheetName,
|
|
74966
|
+
getUniqueText,
|
|
74819
74967
|
isNumber,
|
|
74820
74968
|
isDateTime,
|
|
74821
74969
|
};
|
|
@@ -74914,6 +75062,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
74914
75062
|
exports.AbstractFigureClipboardHandler = AbstractFigureClipboardHandler;
|
|
74915
75063
|
exports.CellErrorType = CellErrorType;
|
|
74916
75064
|
exports.CorePlugin = CorePlugin;
|
|
75065
|
+
exports.CoreViewPlugin = CoreViewPlugin;
|
|
74917
75066
|
exports.DispatchResult = DispatchResult;
|
|
74918
75067
|
exports.EvaluationError = EvaluationError;
|
|
74919
75068
|
exports.Model = Model;
|
|
@@ -74956,9 +75105,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
74956
75105
|
exports.tokenize = tokenize;
|
|
74957
75106
|
|
|
74958
75107
|
|
|
74959
|
-
__info__.version = "18.
|
|
74960
|
-
__info__.date = "2025-01-14T11:
|
|
74961
|
-
__info__.hash = "
|
|
75108
|
+
__info__.version = "18.2.0-alpha.1";
|
|
75109
|
+
__info__.date = "2025-01-14T11:35:51.135Z";
|
|
75110
|
+
__info__.hash = "702f816";
|
|
74962
75111
|
|
|
74963
75112
|
|
|
74964
75113
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|