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