@odoo/o-spreadsheet 18.2.0-alpha.0 → 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 +700 -427
- package/dist/o-spreadsheet.d.ts +88 -34
- package/dist/o-spreadsheet.esm.js +701 -429
- package/dist/o-spreadsheet.iife.js +700 -427
- package/dist/o-spreadsheet.iife.min.js +394 -383
- package/dist/o_spreadsheet.xml +5 -5
- package/package.json +2 -2
|
@@ -2,12 +2,12 @@
|
|
|
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.2.0-alpha.
|
|
6
|
-
* @date
|
|
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
|
-
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
10
|
+
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
11
11
|
|
|
12
12
|
function createActions(menuItems) {
|
|
13
13
|
return menuItems.map(createAction).sort((a, b) => a.sequence - b.sequence);
|
|
@@ -355,6 +355,7 @@ var ComponentsImportance;
|
|
|
355
355
|
ComponentsImportance[ComponentsImportance["Popover"] = 35] = "Popover";
|
|
356
356
|
ComponentsImportance[ComponentsImportance["FigureAnchor"] = 1000] = "FigureAnchor";
|
|
357
357
|
ComponentsImportance[ComponentsImportance["FigureSnapLine"] = 1001] = "FigureSnapLine";
|
|
358
|
+
ComponentsImportance[ComponentsImportance["FigureTooltip"] = 1002] = "FigureTooltip";
|
|
358
359
|
})(ComponentsImportance || (ComponentsImportance = {}));
|
|
359
360
|
let DEFAULT_SHEETVIEW_SIZE = 0;
|
|
360
361
|
function getDefaultSheetViewSize() {
|
|
@@ -974,6 +975,16 @@ function transpose2dPOJO(pojo) {
|
|
|
974
975
|
}
|
|
975
976
|
return result;
|
|
976
977
|
}
|
|
978
|
+
function getUniqueText(text, texts, options = {}) {
|
|
979
|
+
const compute = options.compute ?? ((text, i) => `${text} (${i})`);
|
|
980
|
+
const computeFirstOne = options.computeFirstOne ?? false;
|
|
981
|
+
let i = options.start ?? 1;
|
|
982
|
+
let newText = computeFirstOne ? compute(text, i) : text;
|
|
983
|
+
while (texts.includes(newText)) {
|
|
984
|
+
newText = compute(text, i++);
|
|
985
|
+
}
|
|
986
|
+
return newText;
|
|
987
|
+
}
|
|
977
988
|
|
|
978
989
|
const RBA_REGEX = /rgba?\(|\s+|\)/gi;
|
|
979
990
|
const HEX_MATCH = /^#([A-F\d]{2}){3,4}$/;
|
|
@@ -3709,6 +3720,7 @@ var CommandResult;
|
|
|
3709
3720
|
CommandResult["SheetIsHidden"] = "SheetIsHidden";
|
|
3710
3721
|
CommandResult["InvalidTableResize"] = "InvalidTableResize";
|
|
3711
3722
|
CommandResult["PivotIdNotFound"] = "PivotIdNotFound";
|
|
3723
|
+
CommandResult["PivotInError"] = "PivotInError";
|
|
3712
3724
|
CommandResult["EmptyName"] = "EmptyName";
|
|
3713
3725
|
CommandResult["ValueCellIsInvalidFormula"] = "ValueCellIsInvalidFormula";
|
|
3714
3726
|
CommandResult["InvalidDefinition"] = "InvalidDefinition";
|
|
@@ -6026,10 +6038,10 @@ class RangeImpl {
|
|
|
6026
6038
|
}
|
|
6027
6039
|
}
|
|
6028
6040
|
/**
|
|
6029
|
-
*
|
|
6041
|
+
* Duplicate a range. If the range is on the sheetIdFrom, the range will target
|
|
6030
6042
|
* sheetIdTo.
|
|
6031
6043
|
*/
|
|
6032
|
-
function
|
|
6044
|
+
function duplicateRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, range) {
|
|
6033
6045
|
const sheetId = range.sheetId === sheetIdFrom ? sheetIdTo : range.sheetId;
|
|
6034
6046
|
return range.clone({ sheetId });
|
|
6035
6047
|
}
|
|
@@ -7477,18 +7489,18 @@ function predictLinearValues(Y, X, newX, computeIntercept) {
|
|
|
7477
7489
|
});
|
|
7478
7490
|
return newY.length === newX.length ? newY : transposeMatrix(newY);
|
|
7479
7491
|
}
|
|
7480
|
-
function getMovingAverageValues(dataset, windowSize = DEFAULT_WINDOW_SIZE) {
|
|
7492
|
+
function getMovingAverageValues(dataset, labels, windowSize = DEFAULT_WINDOW_SIZE) {
|
|
7481
7493
|
const values = [];
|
|
7482
7494
|
// Fill the starting values with null until we have a full window
|
|
7483
7495
|
for (let i = 0; i < windowSize - 1; i++) {
|
|
7484
|
-
values.push(
|
|
7496
|
+
values.push({ x: labels[i], y: NaN });
|
|
7485
7497
|
}
|
|
7486
7498
|
for (let i = 0; i <= dataset.length - windowSize; i++) {
|
|
7487
7499
|
let sum = 0;
|
|
7488
7500
|
for (let j = i; j < i + windowSize; j++) {
|
|
7489
7501
|
sum += dataset[j];
|
|
7490
7502
|
}
|
|
7491
|
-
values.push(sum / windowSize);
|
|
7503
|
+
values.push({ x: labels[i + windowSize - 1], y: sum / windowSize });
|
|
7492
7504
|
}
|
|
7493
7505
|
return values;
|
|
7494
7506
|
}
|
|
@@ -9462,6 +9474,150 @@ class ComposerFocusStore extends SpreadsheetStore {
|
|
|
9462
9474
|
}
|
|
9463
9475
|
}
|
|
9464
9476
|
|
|
9477
|
+
/**
|
|
9478
|
+
* This file is largely inspired by owl 1.
|
|
9479
|
+
* `css` tag has been removed from owl 2 without workaround to manage css.
|
|
9480
|
+
* So, the solution was to import the behavior of owl 1 directly in our
|
|
9481
|
+
* codebase, with one difference: the css is added to the sheet as soon as the
|
|
9482
|
+
* css tag is executed. In owl 1, the css was added as soon as a Component was
|
|
9483
|
+
* created for the first time.
|
|
9484
|
+
*/
|
|
9485
|
+
const STYLESHEETS = {};
|
|
9486
|
+
let nextId = 0;
|
|
9487
|
+
/**
|
|
9488
|
+
* CSS tag helper for defining inline stylesheets. With this, one can simply define
|
|
9489
|
+
* an inline stylesheet with just the following code:
|
|
9490
|
+
* ```js
|
|
9491
|
+
* css`.component-a { color: red; }`;
|
|
9492
|
+
* ```
|
|
9493
|
+
*/
|
|
9494
|
+
function css(strings, ...args) {
|
|
9495
|
+
const name = `__sheet__${nextId++}`;
|
|
9496
|
+
const value = String.raw(strings, ...args);
|
|
9497
|
+
registerSheet(name, value);
|
|
9498
|
+
activateSheet(name);
|
|
9499
|
+
return name;
|
|
9500
|
+
}
|
|
9501
|
+
function processSheet(str) {
|
|
9502
|
+
const tokens = str.split(/(\{|\}|;)/).map((s) => s.trim());
|
|
9503
|
+
const selectorStack = [];
|
|
9504
|
+
const parts = [];
|
|
9505
|
+
let rules = [];
|
|
9506
|
+
function generateSelector(stackIndex, parentSelector) {
|
|
9507
|
+
const parts = [];
|
|
9508
|
+
for (const selector of selectorStack[stackIndex]) {
|
|
9509
|
+
let part = (parentSelector && parentSelector + " " + selector) || selector;
|
|
9510
|
+
if (part.includes("&")) {
|
|
9511
|
+
part = selector.replace(/&/g, parentSelector || "");
|
|
9512
|
+
}
|
|
9513
|
+
if (stackIndex < selectorStack.length - 1) {
|
|
9514
|
+
part = generateSelector(stackIndex + 1, part);
|
|
9515
|
+
}
|
|
9516
|
+
parts.push(part);
|
|
9517
|
+
}
|
|
9518
|
+
return parts.join(", ");
|
|
9519
|
+
}
|
|
9520
|
+
function generateRules() {
|
|
9521
|
+
if (rules.length) {
|
|
9522
|
+
parts.push(generateSelector(0) + " {");
|
|
9523
|
+
parts.push(...rules);
|
|
9524
|
+
parts.push("}");
|
|
9525
|
+
rules = [];
|
|
9526
|
+
}
|
|
9527
|
+
}
|
|
9528
|
+
while (tokens.length) {
|
|
9529
|
+
let token = tokens.shift();
|
|
9530
|
+
if (token === "}") {
|
|
9531
|
+
generateRules();
|
|
9532
|
+
selectorStack.pop();
|
|
9533
|
+
}
|
|
9534
|
+
else {
|
|
9535
|
+
if (tokens[0] === "{") {
|
|
9536
|
+
generateRules();
|
|
9537
|
+
selectorStack.push(token.split(/\s*,\s*/));
|
|
9538
|
+
tokens.shift();
|
|
9539
|
+
}
|
|
9540
|
+
if (tokens[0] === ";") {
|
|
9541
|
+
rules.push(" " + token + ";");
|
|
9542
|
+
}
|
|
9543
|
+
}
|
|
9544
|
+
}
|
|
9545
|
+
return parts.join("\n");
|
|
9546
|
+
}
|
|
9547
|
+
function registerSheet(id, css) {
|
|
9548
|
+
const sheet = document.createElement("style");
|
|
9549
|
+
sheet.textContent = processSheet(css);
|
|
9550
|
+
STYLESHEETS[id] = sheet;
|
|
9551
|
+
}
|
|
9552
|
+
function activateSheet(id) {
|
|
9553
|
+
const sheet = STYLESHEETS[id];
|
|
9554
|
+
sheet.setAttribute("component", id);
|
|
9555
|
+
document.head.appendChild(sheet);
|
|
9556
|
+
}
|
|
9557
|
+
function getTextDecoration({ strikethrough, underline, }) {
|
|
9558
|
+
if (!strikethrough && !underline) {
|
|
9559
|
+
return "none";
|
|
9560
|
+
}
|
|
9561
|
+
return `${strikethrough ? "line-through" : ""} ${underline ? "underline" : ""}`;
|
|
9562
|
+
}
|
|
9563
|
+
/**
|
|
9564
|
+
* Convert the cell style to CSS properties.
|
|
9565
|
+
*/
|
|
9566
|
+
function cellStyleToCss(style) {
|
|
9567
|
+
const attributes = cellTextStyleToCss(style);
|
|
9568
|
+
if (!style)
|
|
9569
|
+
return attributes;
|
|
9570
|
+
if (style.fillColor) {
|
|
9571
|
+
attributes["background"] = style.fillColor;
|
|
9572
|
+
}
|
|
9573
|
+
return attributes;
|
|
9574
|
+
}
|
|
9575
|
+
/**
|
|
9576
|
+
* Convert the cell text style to CSS properties.
|
|
9577
|
+
*/
|
|
9578
|
+
function cellTextStyleToCss(style) {
|
|
9579
|
+
const attributes = {};
|
|
9580
|
+
if (!style)
|
|
9581
|
+
return attributes;
|
|
9582
|
+
if (style.bold) {
|
|
9583
|
+
attributes["font-weight"] = "bold";
|
|
9584
|
+
}
|
|
9585
|
+
if (style.italic) {
|
|
9586
|
+
attributes["font-style"] = "italic";
|
|
9587
|
+
}
|
|
9588
|
+
if (style.strikethrough || style.underline) {
|
|
9589
|
+
let decoration = style.strikethrough ? "line-through" : "";
|
|
9590
|
+
decoration = style.underline ? decoration + " underline" : decoration;
|
|
9591
|
+
attributes["text-decoration"] = decoration;
|
|
9592
|
+
}
|
|
9593
|
+
if (style.textColor) {
|
|
9594
|
+
attributes["color"] = style.textColor;
|
|
9595
|
+
}
|
|
9596
|
+
return attributes;
|
|
9597
|
+
}
|
|
9598
|
+
/**
|
|
9599
|
+
* Transform CSS properties into a CSS string.
|
|
9600
|
+
*/
|
|
9601
|
+
function cssPropertiesToCss(attributes) {
|
|
9602
|
+
let styleStr = "";
|
|
9603
|
+
for (const attName in attributes) {
|
|
9604
|
+
if (!attributes[attName]) {
|
|
9605
|
+
continue;
|
|
9606
|
+
}
|
|
9607
|
+
styleStr += `${attName}:${attributes[attName]}; `;
|
|
9608
|
+
}
|
|
9609
|
+
return styleStr;
|
|
9610
|
+
}
|
|
9611
|
+
function getElementMargins(el) {
|
|
9612
|
+
const style = window.getComputedStyle(el);
|
|
9613
|
+
return {
|
|
9614
|
+
top: parseInt(style.marginTop, 10) || 0,
|
|
9615
|
+
bottom: parseInt(style.marginBottom, 10) || 0,
|
|
9616
|
+
left: parseInt(style.marginLeft, 10) || 0,
|
|
9617
|
+
right: parseInt(style.marginRight, 10) || 0,
|
|
9618
|
+
};
|
|
9619
|
+
}
|
|
9620
|
+
|
|
9465
9621
|
const TREND_LINE_XAXIS_ID = "x1";
|
|
9466
9622
|
/**
|
|
9467
9623
|
* This file contains helpers that are common to different charts (mainly
|
|
@@ -9514,25 +9670,25 @@ function updateChartRangesWithDataSets(getters, applyChange, chartDataSets, char
|
|
|
9514
9670
|
};
|
|
9515
9671
|
}
|
|
9516
9672
|
/**
|
|
9517
|
-
*
|
|
9673
|
+
* Duplicate the dataSets. All ranges on sheetIdFrom are adapted to target
|
|
9518
9674
|
* sheetIdTo.
|
|
9519
9675
|
*/
|
|
9520
|
-
function
|
|
9676
|
+
function duplicateDataSetsInDuplicatedSheet(sheetIdFrom, sheetIdTo, dataSets) {
|
|
9521
9677
|
return dataSets.map((ds) => {
|
|
9522
9678
|
return {
|
|
9523
|
-
dataRange:
|
|
9679
|
+
dataRange: duplicateRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, ds.dataRange),
|
|
9524
9680
|
labelCell: ds.labelCell
|
|
9525
|
-
?
|
|
9681
|
+
? duplicateRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, ds.labelCell)
|
|
9526
9682
|
: undefined,
|
|
9527
9683
|
};
|
|
9528
9684
|
});
|
|
9529
9685
|
}
|
|
9530
9686
|
/**
|
|
9531
|
-
*
|
|
9687
|
+
* Duplicate a range. If the range is on the sheetIdFrom, the range will target
|
|
9532
9688
|
* sheetIdTo.
|
|
9533
9689
|
*/
|
|
9534
|
-
function
|
|
9535
|
-
return range ?
|
|
9690
|
+
function duplicateLabelRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, range) {
|
|
9691
|
+
return range ? duplicateRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, range) : undefined;
|
|
9536
9692
|
}
|
|
9537
9693
|
/**
|
|
9538
9694
|
* Adapt a single range of a chart
|
|
@@ -9785,10 +9941,11 @@ function formatTickValue(localeFormat) {
|
|
|
9785
9941
|
if (isNaN(value))
|
|
9786
9942
|
return value;
|
|
9787
9943
|
const { locale, format } = localeFormat;
|
|
9788
|
-
|
|
9944
|
+
const formattedValue = formatValue(value, {
|
|
9789
9945
|
locale,
|
|
9790
9946
|
format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
|
|
9791
9947
|
});
|
|
9948
|
+
return truncateLabel(formattedValue);
|
|
9792
9949
|
};
|
|
9793
9950
|
}
|
|
9794
9951
|
const CHART_AXIS_CHOICES = [
|
|
@@ -9803,6 +9960,15 @@ function getPieColors(colors, dataSetsValues) {
|
|
|
9803
9960
|
}
|
|
9804
9961
|
return pieColors;
|
|
9805
9962
|
}
|
|
9963
|
+
function truncateLabel(label) {
|
|
9964
|
+
if (!label) {
|
|
9965
|
+
return "";
|
|
9966
|
+
}
|
|
9967
|
+
if (label.length > MAX_CHAR_LABEL) {
|
|
9968
|
+
return label.substring(0, MAX_CHAR_LABEL) + "…";
|
|
9969
|
+
}
|
|
9970
|
+
return label;
|
|
9971
|
+
}
|
|
9806
9972
|
|
|
9807
9973
|
/** This is a chartJS plugin that will draw the values of each data next to the point/bar/pie slice */
|
|
9808
9974
|
const chartShowValuesPlugin = {
|
|
@@ -9998,6 +10164,18 @@ function getNextNonEmptyBar(bars, startIndex) {
|
|
|
9998
10164
|
|
|
9999
10165
|
window.Chart?.register(waterfallLinesPlugin);
|
|
10000
10166
|
window.Chart?.register(chartShowValuesPlugin);
|
|
10167
|
+
css /* scss */ `
|
|
10168
|
+
.o-spreadsheet {
|
|
10169
|
+
.o-chart-custom-tooltip {
|
|
10170
|
+
font-size: 12px;
|
|
10171
|
+
background-color: #fff;
|
|
10172
|
+
z-index: ${ComponentsImportance.FigureTooltip};
|
|
10173
|
+
table td span {
|
|
10174
|
+
box-sizing: border-box;
|
|
10175
|
+
}
|
|
10176
|
+
}
|
|
10177
|
+
}
|
|
10178
|
+
`;
|
|
10001
10179
|
class ChartJsComponent extends Component {
|
|
10002
10180
|
static template = "o-spreadsheet-ChartJsComponent";
|
|
10003
10181
|
static props = {
|
|
@@ -10236,11 +10414,11 @@ let ScorecardChart$1 = class ScorecardChart extends AbstractChart {
|
|
|
10236
10414
|
keyValue: keyValueZone ? zoneToXc(keyValueZone) : undefined,
|
|
10237
10415
|
};
|
|
10238
10416
|
}
|
|
10239
|
-
|
|
10240
|
-
const baseline =
|
|
10241
|
-
const keyValue =
|
|
10242
|
-
const definition = this.getDefinitionWithSpecificRanges(baseline, keyValue,
|
|
10243
|
-
return new ScorecardChart(definition,
|
|
10417
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
10418
|
+
const baseline = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.baseline);
|
|
10419
|
+
const keyValue = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.keyValue);
|
|
10420
|
+
const definition = this.getDefinitionWithSpecificRanges(baseline, keyValue, newSheetId);
|
|
10421
|
+
return new ScorecardChart(definition, newSheetId, this.getters);
|
|
10244
10422
|
}
|
|
10245
10423
|
copyInSheetId(sheetId) {
|
|
10246
10424
|
const definition = this.getDefinitionWithSpecificRanges(this.baseline, this.keyValue, sheetId);
|
|
@@ -19930,6 +20108,17 @@ const TEXT = {
|
|
|
19930
20108
|
},
|
|
19931
20109
|
isExported: true,
|
|
19932
20110
|
};
|
|
20111
|
+
// -----------------------------------------------------------------------------
|
|
20112
|
+
// VALUE
|
|
20113
|
+
// -----------------------------------------------------------------------------
|
|
20114
|
+
const VALUE = {
|
|
20115
|
+
description: _t("Converts a string to a numeric value."),
|
|
20116
|
+
args: [arg("value (number)", _t("the string to be converted"))],
|
|
20117
|
+
compute: function (value) {
|
|
20118
|
+
return toNumber(value, this.locale);
|
|
20119
|
+
},
|
|
20120
|
+
isExported: true,
|
|
20121
|
+
};
|
|
19933
20122
|
|
|
19934
20123
|
var text = /*#__PURE__*/Object.freeze({
|
|
19935
20124
|
__proto__: null,
|
|
@@ -19952,7 +20141,8 @@ var text = /*#__PURE__*/Object.freeze({
|
|
|
19952
20141
|
TEXT: TEXT,
|
|
19953
20142
|
TEXTJOIN: TEXTJOIN,
|
|
19954
20143
|
TRIM: TRIM,
|
|
19955
|
-
UPPER: UPPER
|
|
20144
|
+
UPPER: UPPER,
|
|
20145
|
+
VALUE: VALUE
|
|
19956
20146
|
});
|
|
19957
20147
|
|
|
19958
20148
|
// -----------------------------------------------------------------------------
|
|
@@ -22555,15 +22745,6 @@ const CHART_COMMON_OPTIONS = {
|
|
|
22555
22745
|
},
|
|
22556
22746
|
animation: false,
|
|
22557
22747
|
};
|
|
22558
|
-
function truncateLabel(label) {
|
|
22559
|
-
if (!label) {
|
|
22560
|
-
return "";
|
|
22561
|
-
}
|
|
22562
|
-
if (label.length > MAX_CHAR_LABEL) {
|
|
22563
|
-
return label.substring(0, MAX_CHAR_LABEL) + "…";
|
|
22564
|
-
}
|
|
22565
|
-
return label;
|
|
22566
|
-
}
|
|
22567
22748
|
function chartToImage(runtime, figure, type) {
|
|
22568
22749
|
// wrap the canvas in a div with a fixed size because chart.js would
|
|
22569
22750
|
// fill the whole page otherwise
|
|
@@ -22885,150 +23066,6 @@ const CONTENT_TYPES_FILE = "[Content_Types].xml";
|
|
|
22885
23066
|
*/
|
|
22886
23067
|
const iconsOnCellRegistry = new Registry();
|
|
22887
23068
|
|
|
22888
|
-
/**
|
|
22889
|
-
* This file is largely inspired by owl 1.
|
|
22890
|
-
* `css` tag has been removed from owl 2 without workaround to manage css.
|
|
22891
|
-
* So, the solution was to import the behavior of owl 1 directly in our
|
|
22892
|
-
* codebase, with one difference: the css is added to the sheet as soon as the
|
|
22893
|
-
* css tag is executed. In owl 1, the css was added as soon as a Component was
|
|
22894
|
-
* created for the first time.
|
|
22895
|
-
*/
|
|
22896
|
-
const STYLESHEETS = {};
|
|
22897
|
-
let nextId = 0;
|
|
22898
|
-
/**
|
|
22899
|
-
* CSS tag helper for defining inline stylesheets. With this, one can simply define
|
|
22900
|
-
* an inline stylesheet with just the following code:
|
|
22901
|
-
* ```js
|
|
22902
|
-
* css`.component-a { color: red; }`;
|
|
22903
|
-
* ```
|
|
22904
|
-
*/
|
|
22905
|
-
function css(strings, ...args) {
|
|
22906
|
-
const name = `__sheet__${nextId++}`;
|
|
22907
|
-
const value = String.raw(strings, ...args);
|
|
22908
|
-
registerSheet(name, value);
|
|
22909
|
-
activateSheet(name);
|
|
22910
|
-
return name;
|
|
22911
|
-
}
|
|
22912
|
-
function processSheet(str) {
|
|
22913
|
-
const tokens = str.split(/(\{|\}|;)/).map((s) => s.trim());
|
|
22914
|
-
const selectorStack = [];
|
|
22915
|
-
const parts = [];
|
|
22916
|
-
let rules = [];
|
|
22917
|
-
function generateSelector(stackIndex, parentSelector) {
|
|
22918
|
-
const parts = [];
|
|
22919
|
-
for (const selector of selectorStack[stackIndex]) {
|
|
22920
|
-
let part = (parentSelector && parentSelector + " " + selector) || selector;
|
|
22921
|
-
if (part.includes("&")) {
|
|
22922
|
-
part = selector.replace(/&/g, parentSelector || "");
|
|
22923
|
-
}
|
|
22924
|
-
if (stackIndex < selectorStack.length - 1) {
|
|
22925
|
-
part = generateSelector(stackIndex + 1, part);
|
|
22926
|
-
}
|
|
22927
|
-
parts.push(part);
|
|
22928
|
-
}
|
|
22929
|
-
return parts.join(", ");
|
|
22930
|
-
}
|
|
22931
|
-
function generateRules() {
|
|
22932
|
-
if (rules.length) {
|
|
22933
|
-
parts.push(generateSelector(0) + " {");
|
|
22934
|
-
parts.push(...rules);
|
|
22935
|
-
parts.push("}");
|
|
22936
|
-
rules = [];
|
|
22937
|
-
}
|
|
22938
|
-
}
|
|
22939
|
-
while (tokens.length) {
|
|
22940
|
-
let token = tokens.shift();
|
|
22941
|
-
if (token === "}") {
|
|
22942
|
-
generateRules();
|
|
22943
|
-
selectorStack.pop();
|
|
22944
|
-
}
|
|
22945
|
-
else {
|
|
22946
|
-
if (tokens[0] === "{") {
|
|
22947
|
-
generateRules();
|
|
22948
|
-
selectorStack.push(token.split(/\s*,\s*/));
|
|
22949
|
-
tokens.shift();
|
|
22950
|
-
}
|
|
22951
|
-
if (tokens[0] === ";") {
|
|
22952
|
-
rules.push(" " + token + ";");
|
|
22953
|
-
}
|
|
22954
|
-
}
|
|
22955
|
-
}
|
|
22956
|
-
return parts.join("\n");
|
|
22957
|
-
}
|
|
22958
|
-
function registerSheet(id, css) {
|
|
22959
|
-
const sheet = document.createElement("style");
|
|
22960
|
-
sheet.textContent = processSheet(css);
|
|
22961
|
-
STYLESHEETS[id] = sheet;
|
|
22962
|
-
}
|
|
22963
|
-
function activateSheet(id) {
|
|
22964
|
-
const sheet = STYLESHEETS[id];
|
|
22965
|
-
sheet.setAttribute("component", id);
|
|
22966
|
-
document.head.appendChild(sheet);
|
|
22967
|
-
}
|
|
22968
|
-
function getTextDecoration({ strikethrough, underline, }) {
|
|
22969
|
-
if (!strikethrough && !underline) {
|
|
22970
|
-
return "none";
|
|
22971
|
-
}
|
|
22972
|
-
return `${strikethrough ? "line-through" : ""} ${underline ? "underline" : ""}`;
|
|
22973
|
-
}
|
|
22974
|
-
/**
|
|
22975
|
-
* Convert the cell style to CSS properties.
|
|
22976
|
-
*/
|
|
22977
|
-
function cellStyleToCss(style) {
|
|
22978
|
-
const attributes = cellTextStyleToCss(style);
|
|
22979
|
-
if (!style)
|
|
22980
|
-
return attributes;
|
|
22981
|
-
if (style.fillColor) {
|
|
22982
|
-
attributes["background"] = style.fillColor;
|
|
22983
|
-
}
|
|
22984
|
-
return attributes;
|
|
22985
|
-
}
|
|
22986
|
-
/**
|
|
22987
|
-
* Convert the cell text style to CSS properties.
|
|
22988
|
-
*/
|
|
22989
|
-
function cellTextStyleToCss(style) {
|
|
22990
|
-
const attributes = {};
|
|
22991
|
-
if (!style)
|
|
22992
|
-
return attributes;
|
|
22993
|
-
if (style.bold) {
|
|
22994
|
-
attributes["font-weight"] = "bold";
|
|
22995
|
-
}
|
|
22996
|
-
if (style.italic) {
|
|
22997
|
-
attributes["font-style"] = "italic";
|
|
22998
|
-
}
|
|
22999
|
-
if (style.strikethrough || style.underline) {
|
|
23000
|
-
let decoration = style.strikethrough ? "line-through" : "";
|
|
23001
|
-
decoration = style.underline ? decoration + " underline" : decoration;
|
|
23002
|
-
attributes["text-decoration"] = decoration;
|
|
23003
|
-
}
|
|
23004
|
-
if (style.textColor) {
|
|
23005
|
-
attributes["color"] = style.textColor;
|
|
23006
|
-
}
|
|
23007
|
-
return attributes;
|
|
23008
|
-
}
|
|
23009
|
-
/**
|
|
23010
|
-
* Transform CSS properties into a CSS string.
|
|
23011
|
-
*/
|
|
23012
|
-
function cssPropertiesToCss(attributes) {
|
|
23013
|
-
let styleStr = "";
|
|
23014
|
-
for (const attName in attributes) {
|
|
23015
|
-
if (!attributes[attName]) {
|
|
23016
|
-
continue;
|
|
23017
|
-
}
|
|
23018
|
-
styleStr += `${attName}:${attributes[attName]}; `;
|
|
23019
|
-
}
|
|
23020
|
-
return styleStr;
|
|
23021
|
-
}
|
|
23022
|
-
function getElementMargins(el) {
|
|
23023
|
-
const style = window.getComputedStyle(el);
|
|
23024
|
-
return {
|
|
23025
|
-
top: parseInt(style.marginTop, 10) || 0,
|
|
23026
|
-
bottom: parseInt(style.marginBottom, 10) || 0,
|
|
23027
|
-
left: parseInt(style.marginLeft, 10) || 0,
|
|
23028
|
-
right: parseInt(style.marginRight, 10) || 0,
|
|
23029
|
-
};
|
|
23030
|
-
}
|
|
23031
|
-
|
|
23032
23069
|
css /* scss */ `
|
|
23033
23070
|
.o-spreadsheet {
|
|
23034
23071
|
.o-icon {
|
|
@@ -24140,7 +24177,7 @@ function convertWidthFromExcel(width) {
|
|
|
24140
24177
|
return width;
|
|
24141
24178
|
return Math.round((width / WIDTH_FACTOR) * 100) / 100;
|
|
24142
24179
|
}
|
|
24143
|
-
function extractStyle(data, styleId, formatId, borderId) {
|
|
24180
|
+
function extractStyle(data, content, styleId, formatId, borderId) {
|
|
24144
24181
|
const style = styleId ? data.styles[styleId] : {};
|
|
24145
24182
|
const format = formatId ? data.formats[formatId] : undefined;
|
|
24146
24183
|
const styles = {
|
|
@@ -24162,7 +24199,7 @@ function extractStyle(data, styleId, formatId, borderId) {
|
|
|
24162
24199
|
vertical: style.verticalAlign
|
|
24163
24200
|
? V_ALIGNMENT_EXPORT_CONVERSION_MAP[style.verticalAlign]
|
|
24164
24201
|
: undefined,
|
|
24165
|
-
wrapText: style.wrapping === "wrap" || undefined,
|
|
24202
|
+
wrapText: style.wrapping === "wrap" || content?.includes(NEWLINE) ? true : undefined,
|
|
24166
24203
|
},
|
|
24167
24204
|
};
|
|
24168
24205
|
styles.font["strike"] = !!style?.strikethrough || undefined;
|
|
@@ -24393,7 +24430,7 @@ function convertFigure(figure, id, sheetData) {
|
|
|
24393
24430
|
return undefined;
|
|
24394
24431
|
}
|
|
24395
24432
|
function isChartData(data) {
|
|
24396
|
-
return "dataSets" in data;
|
|
24433
|
+
return "dataSets" in data && data.dataSets.length > 0;
|
|
24397
24434
|
}
|
|
24398
24435
|
function isImageData(data) {
|
|
24399
24436
|
return "imageSrc" in data;
|
|
@@ -24739,9 +24776,8 @@ function convertRows(sheet, numberOfRows, headerGroups) {
|
|
|
24739
24776
|
}
|
|
24740
24777
|
return rows;
|
|
24741
24778
|
}
|
|
24742
|
-
/** Remove newlines (\n) in shared strings, We do not support them */
|
|
24743
24779
|
function convertSharedStrings(xlsxSharedStrings) {
|
|
24744
|
-
return xlsxSharedStrings.map(
|
|
24780
|
+
return xlsxSharedStrings.map(replaceNewLines);
|
|
24745
24781
|
}
|
|
24746
24782
|
function convertCells(sheet, data, sheetDims, warningManager) {
|
|
24747
24783
|
const cells = {};
|
|
@@ -25829,15 +25865,10 @@ class XlsxMiscExtractor extends XlsxBaseExtractor {
|
|
|
25829
25865
|
getSharedStrings() {
|
|
25830
25866
|
return this.mapOnElements({ parent: this.rootFile.file.xml, query: "si" }, (ssElement) => {
|
|
25831
25867
|
// Shared string can either be a simple text, or a rich text (text with formatting, possibly in multiple parts)
|
|
25832
|
-
if (ssElement.children[0].tagName === "t") {
|
|
25833
|
-
return this.extractTextContent(ssElement) || "";
|
|
25834
|
-
}
|
|
25835
25868
|
// We don't support rich text formatting, we'll only extract the text
|
|
25836
|
-
|
|
25837
|
-
return this.
|
|
25838
|
-
|
|
25839
|
-
}).join("");
|
|
25840
|
-
}
|
|
25869
|
+
return this.mapOnElements({ parent: ssElement, query: "t" }, (textElement) => {
|
|
25870
|
+
return this.extractTextContent(textElement) || "";
|
|
25871
|
+
}).join("");
|
|
25841
25872
|
});
|
|
25842
25873
|
}
|
|
25843
25874
|
}
|
|
@@ -27154,12 +27185,9 @@ migrationStepRegistry
|
|
|
27154
27185
|
}
|
|
27155
27186
|
const oldName = sheet.name;
|
|
27156
27187
|
const escapedName = sanitizeSheetName(oldName, "_");
|
|
27157
|
-
|
|
27158
|
-
|
|
27159
|
-
|
|
27160
|
-
newName = `${escapedName}${i}`;
|
|
27161
|
-
i++;
|
|
27162
|
-
}
|
|
27188
|
+
const newName = getUniqueText(escapedName, namesTaken, {
|
|
27189
|
+
compute: (name, i) => `${name}${i}`,
|
|
27190
|
+
});
|
|
27163
27191
|
sheet.name = newName;
|
|
27164
27192
|
namesTaken.push(newName);
|
|
27165
27193
|
const replaceName = (str) => {
|
|
@@ -27478,6 +27506,13 @@ migrationStepRegistry
|
|
|
27478
27506
|
}
|
|
27479
27507
|
return data;
|
|
27480
27508
|
},
|
|
27509
|
+
})
|
|
27510
|
+
.add("migration_24", {
|
|
27511
|
+
// Empty migration to allow odoo migrate pivot custom sorting.
|
|
27512
|
+
versionFrom: "24",
|
|
27513
|
+
migrate(data) {
|
|
27514
|
+
return data;
|
|
27515
|
+
},
|
|
27481
27516
|
});
|
|
27482
27517
|
function fixOverlappingFilters(data) {
|
|
27483
27518
|
for (let sheet of data.sheets || []) {
|
|
@@ -27505,7 +27540,7 @@ function fixOverlappingFilters(data) {
|
|
|
27505
27540
|
* a breaking change is made in the way the state is handled, and an upgrade
|
|
27506
27541
|
* function should be defined
|
|
27507
27542
|
*/
|
|
27508
|
-
const CURRENT_VERSION =
|
|
27543
|
+
const CURRENT_VERSION = 25;
|
|
27509
27544
|
const INITIAL_SHEET_ID = "Sheet1";
|
|
27510
27545
|
/**
|
|
27511
27546
|
* This function tries to load anything that could look like a valid
|
|
@@ -28406,12 +28441,12 @@ function getTrendDatasetForLineChart(config, data, labels, axisType, locale) {
|
|
|
28406
28441
|
}
|
|
28407
28442
|
const numberOfStep = 5 * trendLabels.length;
|
|
28408
28443
|
const step = (xmax - xmin) / numberOfStep;
|
|
28409
|
-
const
|
|
28410
|
-
const
|
|
28411
|
-
if (!
|
|
28444
|
+
const trendNewLabels = range(xmin, xmax + step / 2, step);
|
|
28445
|
+
const trendValues = interpolateData(config, filteredValues, filteredLabels, trendNewLabels);
|
|
28446
|
+
if (!trendValues.length) {
|
|
28412
28447
|
return;
|
|
28413
28448
|
}
|
|
28414
|
-
return
|
|
28449
|
+
return trendValues;
|
|
28415
28450
|
}
|
|
28416
28451
|
function interpolateData(config, values, labels, newLabels) {
|
|
28417
28452
|
if (values.length < 2 || labels.length < 2 || newLabels.length === 0) {
|
|
@@ -28427,13 +28462,16 @@ function interpolateData(config, values, labels, newLabels) {
|
|
|
28427
28462
|
case "polynomial": {
|
|
28428
28463
|
const order = config.order;
|
|
28429
28464
|
if (!order) {
|
|
28430
|
-
return
|
|
28465
|
+
return newLabels.map((x) => ({ x, y: NaN }));
|
|
28431
28466
|
}
|
|
28432
28467
|
if (order === 1) {
|
|
28433
|
-
return predictLinearValues([values], [normalizedLabels], [normalizedNewLabels], true)[0];
|
|
28468
|
+
return predictLinearValues([values], [normalizedLabels], [normalizedNewLabels], true)[0].map((y, i) => ({ x: newLabels[i], y }));
|
|
28434
28469
|
}
|
|
28435
28470
|
const coeffs = polynomialRegression(values, normalizedLabels, order, true).flat();
|
|
28436
|
-
return normalizedNewLabels.map((
|
|
28471
|
+
return normalizedNewLabels.map((x, i) => ({
|
|
28472
|
+
x: newLabels[i],
|
|
28473
|
+
y: evaluatePolynomial(coeffs, x, order),
|
|
28474
|
+
}));
|
|
28437
28475
|
}
|
|
28438
28476
|
case "exponential": {
|
|
28439
28477
|
const positiveLogValues = [];
|
|
@@ -28445,22 +28483,22 @@ function interpolateData(config, values, labels, newLabels) {
|
|
|
28445
28483
|
}
|
|
28446
28484
|
}
|
|
28447
28485
|
if (!filteredLabels.length) {
|
|
28448
|
-
return
|
|
28486
|
+
return newLabels.map((x) => ({ x, y: NaN }));
|
|
28449
28487
|
}
|
|
28450
|
-
return expM(predictLinearValues([positiveLogValues], [filteredLabels], [normalizedNewLabels], true))[0];
|
|
28488
|
+
return expM(predictLinearValues([positiveLogValues], [filteredLabels], [normalizedNewLabels], true))[0].map((y, i) => ({ x: newLabels[i], y }));
|
|
28451
28489
|
}
|
|
28452
28490
|
case "logarithmic": {
|
|
28453
|
-
return predictLinearValues([values], logM([normalizedLabels]), logM([normalizedNewLabels]), true)[0];
|
|
28491
|
+
return predictLinearValues([values], logM([normalizedLabels]), logM([normalizedNewLabels]), true)[0].map((y, i) => ({ x: newLabels[i], y }));
|
|
28454
28492
|
}
|
|
28455
28493
|
case "trailingMovingAverage": {
|
|
28456
|
-
return getMovingAverageValues(values, config.window);
|
|
28494
|
+
return getMovingAverageValues(values, labels, config.window);
|
|
28457
28495
|
}
|
|
28458
28496
|
default:
|
|
28459
|
-
return
|
|
28497
|
+
return newLabels.map((x) => ({ x, y: NaN }));
|
|
28460
28498
|
}
|
|
28461
28499
|
}
|
|
28462
28500
|
catch (e) {
|
|
28463
|
-
return
|
|
28501
|
+
return newLabels.map((x) => ({ x, y: NaN }));
|
|
28464
28502
|
}
|
|
28465
28503
|
}
|
|
28466
28504
|
function getChartAxisType(chart, labelRange, getters) {
|
|
@@ -28682,7 +28720,7 @@ function getChartDatasetValues(getters, dataSets) {
|
|
|
28682
28720
|
: undefined;
|
|
28683
28721
|
label =
|
|
28684
28722
|
cell && labelRange
|
|
28685
|
-
?
|
|
28723
|
+
? cell.formattedValue
|
|
28686
28724
|
: (label = `${ChartTerms.Series} ${parseInt(dsIndex) + 1}`);
|
|
28687
28725
|
}
|
|
28688
28726
|
else {
|
|
@@ -28696,7 +28734,7 @@ function getChartDatasetValues(getters, dataSets) {
|
|
|
28696
28734
|
// then using the classical aggregation method to sum the values.
|
|
28697
28735
|
data.fill(1);
|
|
28698
28736
|
}
|
|
28699
|
-
else if (data.every((cell) => cell === undefined || cell === null || !isNumber(cell.toString(),
|
|
28737
|
+
else if (data.every((cell) => cell === undefined || cell === null || !isNumber(cell.toString(), DEFAULT_LOCALE))) {
|
|
28700
28738
|
continue;
|
|
28701
28739
|
}
|
|
28702
28740
|
datasetValues.push({ data, label });
|
|
@@ -28772,7 +28810,7 @@ function getWaterfallDatasetAndLabels(definition, args) {
|
|
|
28772
28810
|
}
|
|
28773
28811
|
return {
|
|
28774
28812
|
datasets: [dataset],
|
|
28775
|
-
labels: labelsWithSubTotals
|
|
28813
|
+
labels: labelsWithSubTotals,
|
|
28776
28814
|
};
|
|
28777
28815
|
}
|
|
28778
28816
|
function getLineChartDatasets(definition, args) {
|
|
@@ -29021,7 +29059,7 @@ function getPieChartLegend(definition, args) {
|
|
|
29021
29059
|
generateLabels: (c) =>
|
|
29022
29060
|
//@ts-ignore
|
|
29023
29061
|
c.data.labels.map((label, index) => ({
|
|
29024
|
-
text: label,
|
|
29062
|
+
text: truncateLabel(String(label)),
|
|
29025
29063
|
strokeStyle: colors[index],
|
|
29026
29064
|
fillStyle: colors[index],
|
|
29027
29065
|
pointStyle: "rect",
|
|
@@ -29090,6 +29128,7 @@ function getWaterfallChartLegend(definition, args) {
|
|
|
29090
29128
|
return legendValues;
|
|
29091
29129
|
},
|
|
29092
29130
|
},
|
|
29131
|
+
onClick: () => { }, // Disables click interaction with the waterfall chart legend items
|
|
29093
29132
|
};
|
|
29094
29133
|
}
|
|
29095
29134
|
function getRadarChartLegend(definition, args) {
|
|
@@ -29151,7 +29190,7 @@ function getCustomLegendLabels(fontColor, legendLabelConfig) {
|
|
|
29151
29190
|
generateLabels: (chart) => chart.data.datasets.map((dataset, index) => {
|
|
29152
29191
|
if (dataset["xAxisID"] === TREND_LINE_XAXIS_ID) {
|
|
29153
29192
|
return {
|
|
29154
|
-
text: dataset.label
|
|
29193
|
+
text: truncateLabel(dataset.label),
|
|
29155
29194
|
fontColor,
|
|
29156
29195
|
strokeStyle: dataset.borderColor,
|
|
29157
29196
|
hidden: !chart.isDatasetVisible(index),
|
|
@@ -29161,7 +29200,7 @@ function getCustomLegendLabels(fontColor, legendLabelConfig) {
|
|
|
29161
29200
|
};
|
|
29162
29201
|
}
|
|
29163
29202
|
return {
|
|
29164
|
-
text: dataset.label
|
|
29203
|
+
text: truncateLabel(dataset.label),
|
|
29165
29204
|
fontColor,
|
|
29166
29205
|
strokeStyle: dataset.borderColor,
|
|
29167
29206
|
fillStyle: dataset.backgroundColor,
|
|
@@ -29231,14 +29270,19 @@ function getLineChartScales(definition, args) {
|
|
|
29231
29270
|
/* We add a second x axis here to draw the trend lines, with the labels length being
|
|
29232
29271
|
* set so that the second axis points match the classical x axis
|
|
29233
29272
|
*/
|
|
29234
|
-
const maxLength = Math.max(...trendDatasets.map((trendDataset) => trendDataset?.length || 0));
|
|
29235
29273
|
scales[TREND_LINE_XAXIS_ID] = {
|
|
29236
29274
|
...scales.x,
|
|
29237
|
-
type: "category",
|
|
29238
|
-
labels: range(0, maxLength).map((x) => x.toString()),
|
|
29239
|
-
offset: false,
|
|
29240
29275
|
display: false,
|
|
29241
29276
|
};
|
|
29277
|
+
if (axisType === "category" || axisType === "time") {
|
|
29278
|
+
/* We add a second x axis here to draw the trend lines, with the labels length being
|
|
29279
|
+
* set so that the second axis points match the classical x axis
|
|
29280
|
+
*/
|
|
29281
|
+
const maxLength = Math.max(...trendDatasets.map((trendDataset) => trendDataset?.length || 0));
|
|
29282
|
+
scales[TREND_LINE_XAXIS_ID]["type"] = "category";
|
|
29283
|
+
scales[TREND_LINE_XAXIS_ID]["labels"] = range(0, maxLength).map((x) => x.toString());
|
|
29284
|
+
scales[TREND_LINE_XAXIS_ID]["offset"] = false;
|
|
29285
|
+
}
|
|
29242
29286
|
}
|
|
29243
29287
|
return scales;
|
|
29244
29288
|
}
|
|
@@ -29303,7 +29347,10 @@ function getRadarChartScales(definition, args) {
|
|
|
29303
29347
|
callback: formatTickValue({ format: axisFormats?.r, locale }),
|
|
29304
29348
|
backdropColor: definition.background || "#FFFFFF",
|
|
29305
29349
|
},
|
|
29306
|
-
pointLabels: {
|
|
29350
|
+
pointLabels: {
|
|
29351
|
+
color: chartFontColor(definition.background),
|
|
29352
|
+
callback: truncateLabel,
|
|
29353
|
+
},
|
|
29307
29354
|
suggestedMin: minValue < 0 ? minValue - 1 : 0,
|
|
29308
29355
|
},
|
|
29309
29356
|
};
|
|
@@ -29400,6 +29447,11 @@ function getChartAxis(definition, position, type, options) {
|
|
|
29400
29447
|
ticks: {
|
|
29401
29448
|
padding: 5,
|
|
29402
29449
|
color: fontColor,
|
|
29450
|
+
callback: function (tickValue) {
|
|
29451
|
+
// Category axis callback's internal tick value is the index of the label
|
|
29452
|
+
// https://www.chartjs.org/docs/latest/axes/labelling.html#creating-custom-tick-formats
|
|
29453
|
+
return truncateLabel(this.getLabelForValue(tickValue));
|
|
29454
|
+
},
|
|
29403
29455
|
},
|
|
29404
29456
|
grid: {
|
|
29405
29457
|
display: false,
|
|
@@ -29479,8 +29531,70 @@ function getChartTitle(definition) {
|
|
|
29479
29531
|
};
|
|
29480
29532
|
}
|
|
29481
29533
|
|
|
29534
|
+
/**
|
|
29535
|
+
* Custom tooltip for the charts. Mostly copied from Odoo's custom tooltip, with some slight changes to make it work
|
|
29536
|
+
* with o-spreadsheet chart data and CSS.
|
|
29537
|
+
*
|
|
29538
|
+
* https://github.com/odoo/odoo/blob/18.0/addons/web/static/src/views/graph/graph_renderer.xml
|
|
29539
|
+
*/
|
|
29540
|
+
const templates = /* xml */ `
|
|
29541
|
+
<templates>
|
|
29542
|
+
<t t-name="o-spreadsheet-CustomTooltip">
|
|
29543
|
+
<div
|
|
29544
|
+
class="o-chart-custom-tooltip border rounded px-2 py-1 pe-none mw-100 position-absolute text-nowrap shadow opacity-100">
|
|
29545
|
+
<table class="overflow-hidden m-0">
|
|
29546
|
+
<thead>
|
|
29547
|
+
<tr>
|
|
29548
|
+
<th class="o-tooltip-title align-baseline border-0 text-truncate" t-esc="title" t-attf-style="max-width: {{ labelsMaxWidth }}"/>
|
|
29549
|
+
</tr>
|
|
29550
|
+
</thead>
|
|
29551
|
+
<tbody>
|
|
29552
|
+
<tr t-foreach="tooltipItems" t-as="tooltipItem" t-key="tooltipItem_index">
|
|
29553
|
+
<td>
|
|
29554
|
+
<span
|
|
29555
|
+
class="badge ps-2 py-2 rounded-0 align-middle"
|
|
29556
|
+
t-attf-style="background-color: {{ tooltipItem.boxColor }}"
|
|
29557
|
+
> </span>
|
|
29558
|
+
<small
|
|
29559
|
+
t-if="tooltipItem.label"
|
|
29560
|
+
class="o-tooltip-label d-inline-block text-truncate align-middle smaller ms-2"
|
|
29561
|
+
t-esc="tooltipItem.label"
|
|
29562
|
+
t-attf-style="max-width: {{ labelsMaxWidth }}"
|
|
29563
|
+
/>
|
|
29564
|
+
</td>
|
|
29565
|
+
<td class="o-tooltip-value ps-2 fw-bolder text-end">
|
|
29566
|
+
<small class="smaller d-inline-block text-truncate align-middle" t-attf-style="max-width: {{ valuesMaxWidth }}">
|
|
29567
|
+
<t t-esc="tooltipItem.value"/>
|
|
29568
|
+
<t t-if="tooltipItem.percentage">
|
|
29569
|
+
(
|
|
29570
|
+
<t t-esc="tooltipItem.percentage"/>
|
|
29571
|
+
%)
|
|
29572
|
+
</t>
|
|
29573
|
+
</small>
|
|
29574
|
+
</td>
|
|
29575
|
+
</tr>
|
|
29576
|
+
</tbody>
|
|
29577
|
+
</table>
|
|
29578
|
+
</div>
|
|
29579
|
+
</t>
|
|
29580
|
+
</templates>
|
|
29581
|
+
`;
|
|
29582
|
+
const app = new App(Component, { templates, translateFn: _t });
|
|
29583
|
+
function renderToString(templateName, context = {}) {
|
|
29584
|
+
return render(templateName, context).innerHTML;
|
|
29585
|
+
}
|
|
29586
|
+
function render(templateName, context = {}) {
|
|
29587
|
+
const templateFn = app.getTemplate(templateName);
|
|
29588
|
+
const bdom = templateFn(context, {});
|
|
29589
|
+
const div = document.createElement("div");
|
|
29590
|
+
blockDom.mount(bdom, div);
|
|
29591
|
+
return div;
|
|
29592
|
+
}
|
|
29593
|
+
|
|
29482
29594
|
function getBarChartTooltip(definition, args) {
|
|
29483
29595
|
return {
|
|
29596
|
+
enabled: false,
|
|
29597
|
+
external: customTooltipHandler,
|
|
29484
29598
|
callbacks: {
|
|
29485
29599
|
title: function (tooltipItems) {
|
|
29486
29600
|
return tooltipItems.some((item) => item.dataset.xAxisID !== TREND_LINE_XAXIS_ID)
|
|
@@ -29504,11 +29618,17 @@ function getBarChartTooltip(definition, args) {
|
|
|
29504
29618
|
function getLineChartTooltip(definition, args) {
|
|
29505
29619
|
const { axisType, locale, axisFormats } = args;
|
|
29506
29620
|
const labelFormat = axisFormats?.x;
|
|
29507
|
-
const tooltip = {
|
|
29621
|
+
const tooltip = {
|
|
29622
|
+
enabled: false,
|
|
29623
|
+
external: customTooltipHandler,
|
|
29624
|
+
callbacks: {},
|
|
29625
|
+
};
|
|
29508
29626
|
if (axisType === "linear") {
|
|
29509
29627
|
tooltip.callbacks.label = (tooltipItem) => {
|
|
29510
29628
|
const dataSetPoint = tooltipItem.parsed.y;
|
|
29511
|
-
let label = tooltipItem.
|
|
29629
|
+
let label = tooltipItem.dataset.xAxisID === TREND_LINE_XAXIS_ID
|
|
29630
|
+
? ""
|
|
29631
|
+
: tooltipItem.parsed.x;
|
|
29512
29632
|
if (typeof label === "string" && isNumber(label, locale)) {
|
|
29513
29633
|
label = toNumber(label, locale);
|
|
29514
29634
|
}
|
|
@@ -29541,6 +29661,8 @@ function getPieChartTooltip(definition, args) {
|
|
|
29541
29661
|
const { locale, axisFormats } = args;
|
|
29542
29662
|
const format = axisFormats?.y || axisFormats?.y1;
|
|
29543
29663
|
return {
|
|
29664
|
+
enabled: false,
|
|
29665
|
+
external: customTooltipHandler,
|
|
29544
29666
|
callbacks: {
|
|
29545
29667
|
title: function (tooltipItems) {
|
|
29546
29668
|
return tooltipItems[0].dataset.label;
|
|
@@ -29565,6 +29687,8 @@ function getWaterfallChartTooltip(definition, args) {
|
|
|
29565
29687
|
const format = axisFormats?.y || axisFormats?.y1;
|
|
29566
29688
|
const dataSeriesLabels = dataSetsValues.map((dataSet) => dataSet.label);
|
|
29567
29689
|
return {
|
|
29690
|
+
enabled: false,
|
|
29691
|
+
external: customTooltipHandler,
|
|
29568
29692
|
callbacks: {
|
|
29569
29693
|
label: function (tooltipItem) {
|
|
29570
29694
|
const [lastValue, currentValue] = tooltipItem.raw;
|
|
@@ -29596,6 +29720,8 @@ function getPyramidChartTooltip(definition, args) {
|
|
|
29596
29720
|
function getRadarChartTooltip(definition, args) {
|
|
29597
29721
|
const { locale, axisFormats } = args;
|
|
29598
29722
|
return {
|
|
29723
|
+
enabled: false,
|
|
29724
|
+
external: customTooltipHandler,
|
|
29599
29725
|
callbacks: {
|
|
29600
29726
|
label: function (tooltipItem) {
|
|
29601
29727
|
const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
|
|
@@ -29634,6 +29760,48 @@ function calculatePercentage(dataset, dataIndex) {
|
|
|
29634
29760
|
const percentage = (dataset[dataIndex] / total) * 100;
|
|
29635
29761
|
return percentage.toFixed(2);
|
|
29636
29762
|
}
|
|
29763
|
+
function customTooltipHandler({ chart, tooltip }) {
|
|
29764
|
+
chart.canvas.parentNode.querySelector("div.o-chart-custom-tooltip")?.remove();
|
|
29765
|
+
if (tooltip.opacity === 0 || tooltip.dataPoints.length === 0) {
|
|
29766
|
+
return;
|
|
29767
|
+
}
|
|
29768
|
+
const tooltipItems = tooltip.body.map((body, index) => {
|
|
29769
|
+
let [label, value] = body.lines[0].split(":").map((str) => str.trim());
|
|
29770
|
+
if (!value) {
|
|
29771
|
+
value = label;
|
|
29772
|
+
label = "";
|
|
29773
|
+
}
|
|
29774
|
+
const color = tooltip.labelColors[index].backgroundColor;
|
|
29775
|
+
return {
|
|
29776
|
+
label,
|
|
29777
|
+
value,
|
|
29778
|
+
boxColor: typeof color === "string" ? setColorAlpha(color, 1) : color,
|
|
29779
|
+
};
|
|
29780
|
+
});
|
|
29781
|
+
const innerHTML = renderToString("o-spreadsheet-CustomTooltip", {
|
|
29782
|
+
labelsMaxWidth: Math.floor(chart.canvas.clientWidth * 0.5) + "px",
|
|
29783
|
+
valuesMaxWidth: Math.floor(chart.canvas.clientWidth * 0.25) + "px",
|
|
29784
|
+
title: tooltip.title[0],
|
|
29785
|
+
tooltipItems,
|
|
29786
|
+
});
|
|
29787
|
+
const template = Object.assign(document.createElement("template"), { innerHTML });
|
|
29788
|
+
const newTooltipEl = template.content.firstChild;
|
|
29789
|
+
chart.canvas.parentNode?.appendChild(newTooltipEl);
|
|
29790
|
+
Object.assign(newTooltipEl.style, {
|
|
29791
|
+
left: getTooltipLeftPosition(chart, tooltip, newTooltipEl.clientWidth) + "px",
|
|
29792
|
+
top: Math.floor(tooltip.caretY - newTooltipEl.clientHeight / 2) + "px",
|
|
29793
|
+
});
|
|
29794
|
+
}
|
|
29795
|
+
/**
|
|
29796
|
+
* Get the left position for the tooltip, making sure it doesn't go out of the chart area.
|
|
29797
|
+
*/
|
|
29798
|
+
function getTooltipLeftPosition(chart, tooltip, tooltipWidth) {
|
|
29799
|
+
const x = tooltip.caretX;
|
|
29800
|
+
if (x + tooltipWidth > chart.chartArea.right) {
|
|
29801
|
+
return Math.max(0, x - tooltipWidth);
|
|
29802
|
+
}
|
|
29803
|
+
return x;
|
|
29804
|
+
}
|
|
29637
29805
|
|
|
29638
29806
|
var CHART_RUNTIME_HELPERS = /*#__PURE__*/Object.freeze({
|
|
29639
29807
|
__proto__: null,
|
|
@@ -29747,11 +29915,11 @@ class BarChart extends AbstractChart {
|
|
|
29747
29915
|
: undefined,
|
|
29748
29916
|
};
|
|
29749
29917
|
}
|
|
29750
|
-
|
|
29751
|
-
const dataSets =
|
|
29752
|
-
const labelRange =
|
|
29753
|
-
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange,
|
|
29754
|
-
return new BarChart(definition,
|
|
29918
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
29919
|
+
const dataSets = duplicateDataSetsInDuplicatedSheet(this.sheetId, newSheetId, this.dataSets);
|
|
29920
|
+
const labelRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.labelRange);
|
|
29921
|
+
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange, newSheetId);
|
|
29922
|
+
return new BarChart(definition, newSheetId, this.getters);
|
|
29755
29923
|
}
|
|
29756
29924
|
copyInSheetId(sheetId) {
|
|
29757
29925
|
const definition = this.getDefinitionWithSpecificDataSets(this.dataSets, this.labelRange, sheetId);
|
|
@@ -29818,7 +29986,7 @@ function createBarChartRuntime(chart, getters) {
|
|
|
29818
29986
|
const config = {
|
|
29819
29987
|
type: "bar",
|
|
29820
29988
|
data: {
|
|
29821
|
-
labels: chartData.labels
|
|
29989
|
+
labels: chartData.labels,
|
|
29822
29990
|
datasets: getBarChartDatasets(definition, chartData),
|
|
29823
29991
|
},
|
|
29824
29992
|
options: {
|
|
@@ -29954,11 +30122,11 @@ class ComboChart extends AbstractChart {
|
|
|
29954
30122
|
showValues: context.showValues,
|
|
29955
30123
|
};
|
|
29956
30124
|
}
|
|
29957
|
-
|
|
29958
|
-
const dataSets =
|
|
29959
|
-
const labelRange =
|
|
29960
|
-
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange,
|
|
29961
|
-
return new ComboChart(definition,
|
|
30125
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
30126
|
+
const dataSets = duplicateDataSetsInDuplicatedSheet(this.sheetId, newSheetId, this.dataSets);
|
|
30127
|
+
const labelRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.labelRange);
|
|
30128
|
+
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange, newSheetId);
|
|
30129
|
+
return new ComboChart(definition, newSheetId, this.getters);
|
|
29962
30130
|
}
|
|
29963
30131
|
copyInSheetId(sheetId) {
|
|
29964
30132
|
const definition = this.getDefinitionWithSpecificDataSets(this.dataSets, this.labelRange, sheetId);
|
|
@@ -29971,7 +30139,7 @@ function createComboChartRuntime(chart, getters) {
|
|
|
29971
30139
|
const config = {
|
|
29972
30140
|
type: "bar",
|
|
29973
30141
|
data: {
|
|
29974
|
-
labels: chartData.labels
|
|
30142
|
+
labels: chartData.labels,
|
|
29975
30143
|
datasets: getComboChartDatasets(definition, chartData),
|
|
29976
30144
|
},
|
|
29977
30145
|
options: {
|
|
@@ -30105,10 +30273,10 @@ class GaugeChart extends AbstractChart {
|
|
|
30105
30273
|
},
|
|
30106
30274
|
};
|
|
30107
30275
|
}
|
|
30108
|
-
|
|
30109
|
-
const dataRange =
|
|
30110
|
-
const definition = this.getDefinitionWithSpecificRanges(dataRange,
|
|
30111
|
-
return new GaugeChart(definition,
|
|
30276
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
30277
|
+
const dataRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.dataRange);
|
|
30278
|
+
const definition = this.getDefinitionWithSpecificRanges(dataRange, newSheetId);
|
|
30279
|
+
return new GaugeChart(definition, newSheetId, this.getters);
|
|
30112
30280
|
}
|
|
30113
30281
|
copyInSheetId(sheetId) {
|
|
30114
30282
|
const definition = this.getDefinitionWithSpecificRanges(this.dataRange, sheetId);
|
|
@@ -30201,7 +30369,11 @@ function createGaugeChartRuntime(chart, getters) {
|
|
|
30201
30369
|
colors.push(chartColors.upperColor);
|
|
30202
30370
|
return {
|
|
30203
30371
|
background: getters.getStyleOfSingleCellChart(chart.background, dataRange).background,
|
|
30204
|
-
title:
|
|
30372
|
+
title: {
|
|
30373
|
+
...chart.title,
|
|
30374
|
+
// chart titles are extracted from .json files and they are translated at runtime here
|
|
30375
|
+
text: _t(chart.title.text ?? ""),
|
|
30376
|
+
},
|
|
30205
30377
|
minValue: {
|
|
30206
30378
|
value: minValue,
|
|
30207
30379
|
label: formatValue(minValue, { locale, format }),
|
|
@@ -30285,11 +30457,11 @@ class GeoChart extends AbstractChart {
|
|
|
30285
30457
|
: undefined,
|
|
30286
30458
|
};
|
|
30287
30459
|
}
|
|
30288
|
-
|
|
30289
|
-
const dataSets =
|
|
30290
|
-
const labelRange =
|
|
30291
|
-
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange,
|
|
30292
|
-
return new GeoChart(definition,
|
|
30460
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
30461
|
+
const dataSets = duplicateDataSetsInDuplicatedSheet(this.sheetId, newSheetId, this.dataSets);
|
|
30462
|
+
const labelRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.labelRange);
|
|
30463
|
+
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange, newSheetId);
|
|
30464
|
+
return new GeoChart(definition, newSheetId, this.getters);
|
|
30293
30465
|
}
|
|
30294
30466
|
copyInSheetId(sheetId) {
|
|
30295
30467
|
const definition = this.getDefinitionWithSpecificDataSets(this.dataSets, this.labelRange, sheetId);
|
|
@@ -30482,11 +30654,11 @@ class LineChart extends AbstractChart {
|
|
|
30482
30654
|
verticalAxis: getDefinedAxis(definition),
|
|
30483
30655
|
};
|
|
30484
30656
|
}
|
|
30485
|
-
|
|
30486
|
-
const dataSets =
|
|
30487
|
-
const labelRange =
|
|
30488
|
-
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange,
|
|
30489
|
-
return new LineChart(definition,
|
|
30657
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
30658
|
+
const dataSets = duplicateDataSetsInDuplicatedSheet(this.sheetId, newSheetId, this.dataSets);
|
|
30659
|
+
const labelRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.labelRange);
|
|
30660
|
+
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange, newSheetId);
|
|
30661
|
+
return new LineChart(definition, newSheetId, this.getters);
|
|
30490
30662
|
}
|
|
30491
30663
|
copyInSheetId(sheetId) {
|
|
30492
30664
|
const definition = this.getDefinitionWithSpecificDataSets(this.dataSets, this.labelRange, sheetId);
|
|
@@ -30499,7 +30671,7 @@ function createLineChartRuntime(chart, getters) {
|
|
|
30499
30671
|
const config = {
|
|
30500
30672
|
type: "line",
|
|
30501
30673
|
data: {
|
|
30502
|
-
labels: chartData.
|
|
30674
|
+
labels: chartData.labels,
|
|
30503
30675
|
datasets: getLineChartDatasets(definition, chartData),
|
|
30504
30676
|
},
|
|
30505
30677
|
options: {
|
|
@@ -30593,11 +30765,11 @@ class PieChart extends AbstractChart {
|
|
|
30593
30765
|
showValues: this.showValues,
|
|
30594
30766
|
};
|
|
30595
30767
|
}
|
|
30596
|
-
|
|
30597
|
-
const dataSets =
|
|
30598
|
-
const labelRange =
|
|
30599
|
-
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange,
|
|
30600
|
-
return new PieChart(definition,
|
|
30768
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
30769
|
+
const dataSets = duplicateDataSetsInDuplicatedSheet(this.sheetId, newSheetId, this.dataSets);
|
|
30770
|
+
const labelRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.labelRange);
|
|
30771
|
+
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange, newSheetId);
|
|
30772
|
+
return new PieChart(definition, newSheetId, this.getters);
|
|
30601
30773
|
}
|
|
30602
30774
|
copyInSheetId(sheetId) {
|
|
30603
30775
|
const definition = this.getDefinitionWithSpecificDataSets(this.dataSets, this.labelRange, sheetId);
|
|
@@ -30634,7 +30806,7 @@ function createPieChartRuntime(chart, getters) {
|
|
|
30634
30806
|
const config = {
|
|
30635
30807
|
type: chart.isDoughnut ? "doughnut" : "pie",
|
|
30636
30808
|
data: {
|
|
30637
|
-
labels: chartData.labels
|
|
30809
|
+
labels: chartData.labels,
|
|
30638
30810
|
datasets: getPieChartDatasets(definition, chartData),
|
|
30639
30811
|
},
|
|
30640
30812
|
options: {
|
|
@@ -30714,11 +30886,11 @@ class PyramidChart extends AbstractChart {
|
|
|
30714
30886
|
: undefined,
|
|
30715
30887
|
};
|
|
30716
30888
|
}
|
|
30717
|
-
|
|
30718
|
-
const dataSets =
|
|
30719
|
-
const labelRange =
|
|
30720
|
-
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange,
|
|
30721
|
-
return new PyramidChart(definition,
|
|
30889
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
30890
|
+
const dataSets = duplicateDataSetsInDuplicatedSheet(this.sheetId, newSheetId, this.dataSets);
|
|
30891
|
+
const labelRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.labelRange);
|
|
30892
|
+
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange, newSheetId);
|
|
30893
|
+
return new PyramidChart(definition, newSheetId, this.getters);
|
|
30722
30894
|
}
|
|
30723
30895
|
copyInSheetId(sheetId) {
|
|
30724
30896
|
const definition = this.getDefinitionWithSpecificDataSets(this.dataSets, this.labelRange, sheetId);
|
|
@@ -30770,7 +30942,7 @@ function createPyramidChartRuntime(chart, getters) {
|
|
|
30770
30942
|
const config = {
|
|
30771
30943
|
type: "bar",
|
|
30772
30944
|
data: {
|
|
30773
|
-
labels: chartData.labels
|
|
30945
|
+
labels: chartData.labels,
|
|
30774
30946
|
datasets: getBarChartDatasets(definition, chartData),
|
|
30775
30947
|
},
|
|
30776
30948
|
options: {
|
|
@@ -30851,11 +31023,11 @@ class RadarChart extends AbstractChart {
|
|
|
30851
31023
|
: undefined,
|
|
30852
31024
|
};
|
|
30853
31025
|
}
|
|
30854
|
-
|
|
30855
|
-
const dataSets =
|
|
30856
|
-
const labelRange =
|
|
30857
|
-
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange,
|
|
30858
|
-
return new RadarChart(definition,
|
|
31026
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
31027
|
+
const dataSets = duplicateDataSetsInDuplicatedSheet(this.sheetId, newSheetId, this.dataSets);
|
|
31028
|
+
const labelRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.labelRange);
|
|
31029
|
+
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange, newSheetId);
|
|
31030
|
+
return new RadarChart(definition, newSheetId, this.getters);
|
|
30859
31031
|
}
|
|
30860
31032
|
copyInSheetId(sheetId) {
|
|
30861
31033
|
const definition = this.getDefinitionWithSpecificDataSets(this.dataSets, this.labelRange, sheetId);
|
|
@@ -30920,7 +31092,7 @@ function createRadarChartRuntime(chart, getters) {
|
|
|
30920
31092
|
const config = {
|
|
30921
31093
|
type: "radar",
|
|
30922
31094
|
data: {
|
|
30923
|
-
labels: chartData.labels
|
|
31095
|
+
labels: chartData.labels,
|
|
30924
31096
|
datasets: getRadarChartDatasets(definition, chartData),
|
|
30925
31097
|
},
|
|
30926
31098
|
options: {
|
|
@@ -31054,11 +31226,11 @@ class ScatterChart extends AbstractChart {
|
|
|
31054
31226
|
verticalAxis: getDefinedAxis(definition),
|
|
31055
31227
|
};
|
|
31056
31228
|
}
|
|
31057
|
-
|
|
31058
|
-
const dataSets =
|
|
31059
|
-
const labelRange =
|
|
31060
|
-
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange,
|
|
31061
|
-
return new ScatterChart(definition,
|
|
31229
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
31230
|
+
const dataSets = duplicateDataSetsInDuplicatedSheet(this.sheetId, newSheetId, this.dataSets);
|
|
31231
|
+
const labelRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.labelRange);
|
|
31232
|
+
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange, newSheetId);
|
|
31233
|
+
return new ScatterChart(definition, newSheetId, this.getters);
|
|
31062
31234
|
}
|
|
31063
31235
|
copyInSheetId(sheetId) {
|
|
31064
31236
|
const definition = this.getDefinitionWithSpecificDataSets(this.dataSets, this.labelRange, sheetId);
|
|
@@ -31073,7 +31245,7 @@ function createScatterChartRuntime(chart, getters) {
|
|
|
31073
31245
|
// have less options than the line chart (it only works with linear labels)
|
|
31074
31246
|
type: "line",
|
|
31075
31247
|
data: {
|
|
31076
|
-
labels: chartData.
|
|
31248
|
+
labels: chartData.labels,
|
|
31077
31249
|
datasets: getScatterChartDatasets(definition, chartData),
|
|
31078
31250
|
},
|
|
31079
31251
|
options: {
|
|
@@ -31171,11 +31343,11 @@ class WaterfallChart extends AbstractChart {
|
|
|
31171
31343
|
: undefined,
|
|
31172
31344
|
};
|
|
31173
31345
|
}
|
|
31174
|
-
|
|
31175
|
-
const dataSets =
|
|
31176
|
-
const labelRange =
|
|
31177
|
-
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange,
|
|
31178
|
-
return new WaterfallChart(definition,
|
|
31346
|
+
duplicateInDuplicatedSheet(newSheetId) {
|
|
31347
|
+
const dataSets = duplicateDataSetsInDuplicatedSheet(this.sheetId, newSheetId, this.dataSets);
|
|
31348
|
+
const labelRange = duplicateLabelRangeInDuplicatedSheet(this.sheetId, newSheetId, this.labelRange);
|
|
31349
|
+
const definition = this.getDefinitionWithSpecificDataSets(dataSets, labelRange, newSheetId);
|
|
31350
|
+
return new WaterfallChart(definition, newSheetId, this.getters);
|
|
31179
31351
|
}
|
|
31180
31352
|
copyInSheetId(sheetId) {
|
|
31181
31353
|
const definition = this.getDefinitionWithSpecificDataSets(this.dataSets, this.labelRange, sheetId);
|
|
@@ -33602,8 +33774,6 @@ var CHART_HELPERS = /*#__PURE__*/Object.freeze({
|
|
|
33602
33774
|
chartToImage: chartToImage,
|
|
33603
33775
|
checkDataset: checkDataset,
|
|
33604
33776
|
checkLabelRange: checkLabelRange,
|
|
33605
|
-
copyDataSetsWithNewSheetId: copyDataSetsWithNewSheetId,
|
|
33606
|
-
copyLabelRangeWithNewSheetId: copyLabelRangeWithNewSheetId,
|
|
33607
33777
|
createBarChartRuntime: createBarChartRuntime,
|
|
33608
33778
|
createDataSets: createDataSets,
|
|
33609
33779
|
createGaugeChartRuntime: createGaugeChartRuntime,
|
|
@@ -33612,6 +33782,8 @@ var CHART_HELPERS = /*#__PURE__*/Object.freeze({
|
|
|
33612
33782
|
createScorecardChartRuntime: createScorecardChartRuntime,
|
|
33613
33783
|
createWaterfallChartRuntime: createWaterfallChartRuntime,
|
|
33614
33784
|
drawScoreChart: drawScoreChart,
|
|
33785
|
+
duplicateDataSetsInDuplicatedSheet: duplicateDataSetsInDuplicatedSheet,
|
|
33786
|
+
duplicateLabelRangeInDuplicatedSheet: duplicateLabelRangeInDuplicatedSheet,
|
|
33615
33787
|
formatChartDatasetValue: formatChartDatasetValue,
|
|
33616
33788
|
formatTickValue: formatTickValue,
|
|
33617
33789
|
getChartPositionAtCenterOfViewport: getChartPositionAtCenterOfViewport,
|
|
@@ -35332,12 +35504,20 @@ function fontSizeMenuBuilder() {
|
|
|
35332
35504
|
});
|
|
35333
35505
|
}
|
|
35334
35506
|
function isAutomaticFormatSelected(env) {
|
|
35335
|
-
const
|
|
35336
|
-
|
|
35507
|
+
const activePosition = env.model.getters.getActivePosition();
|
|
35508
|
+
const pivotCell = env.model.getters.getPivotCellFromPosition(activePosition);
|
|
35509
|
+
if (pivotCell.type === "VALUE") {
|
|
35510
|
+
return !env.model.getters.getEvaluatedCell(activePosition).format;
|
|
35511
|
+
}
|
|
35512
|
+
return !env.model.getters.getCell(activePosition)?.format;
|
|
35337
35513
|
}
|
|
35338
35514
|
function isFormatSelected(env, format) {
|
|
35339
|
-
const
|
|
35340
|
-
|
|
35515
|
+
const activePosition = env.model.getters.getActivePosition();
|
|
35516
|
+
const pivotCell = env.model.getters.getPivotCellFromPosition(activePosition);
|
|
35517
|
+
if (pivotCell.type === "VALUE") {
|
|
35518
|
+
return env.model.getters.getEvaluatedCell(activePosition).format === format;
|
|
35519
|
+
}
|
|
35520
|
+
return env.model.getters.getCell(activePosition)?.format === format;
|
|
35341
35521
|
}
|
|
35342
35522
|
function isFontSizeSelected(env, fontSize) {
|
|
35343
35523
|
const currentFontSize = env.model.getters.getCurrentStyle().fontSize || DEFAULT_FONT_SIZE;
|
|
@@ -39676,14 +39856,11 @@ class ChartPanel extends Component {
|
|
|
39676
39856
|
}
|
|
39677
39857
|
|
|
39678
39858
|
class DOMFocusableElementStore {
|
|
39679
|
-
mutators = ["setFocusableElement"
|
|
39859
|
+
mutators = ["setFocusableElement"];
|
|
39680
39860
|
focusableElement = undefined;
|
|
39681
39861
|
setFocusableElement(element) {
|
|
39682
39862
|
this.focusableElement = element;
|
|
39683
39863
|
}
|
|
39684
|
-
focus() {
|
|
39685
|
-
this.focusableElement?.focus();
|
|
39686
|
-
}
|
|
39687
39864
|
}
|
|
39688
39865
|
|
|
39689
39866
|
css /* scss */ `
|
|
@@ -40331,7 +40508,7 @@ class Composer extends Component {
|
|
|
40331
40508
|
if (document.activeElement === this.contentHelper.el &&
|
|
40332
40509
|
this.props.composerStore.editionMode === "inactive" &&
|
|
40333
40510
|
!this.props.isDefaultFocus) {
|
|
40334
|
-
this.DOMFocusableElementStore.focus();
|
|
40511
|
+
this.DOMFocusableElementStore.focusableElement?.focus();
|
|
40335
40512
|
}
|
|
40336
40513
|
});
|
|
40337
40514
|
useEffect(() => {
|
|
@@ -44312,16 +44489,21 @@ class TextInput extends Component {
|
|
|
44312
44489
|
}
|
|
44313
44490
|
this.inputRef.el?.blur();
|
|
44314
44491
|
}
|
|
44315
|
-
|
|
44316
|
-
|
|
44317
|
-
if (
|
|
44318
|
-
|
|
44319
|
-
|
|
44320
|
-
|
|
44321
|
-
|
|
44322
|
-
|
|
44323
|
-
|
|
44324
|
-
|
|
44492
|
+
onMouseDown(ev) {
|
|
44493
|
+
// Stop the event if the input is not focused, we handle everything in onMouseUp
|
|
44494
|
+
if (ev.target !== document.activeElement) {
|
|
44495
|
+
ev.preventDefault();
|
|
44496
|
+
ev.stopPropagation();
|
|
44497
|
+
}
|
|
44498
|
+
}
|
|
44499
|
+
onMouseUp(ev) {
|
|
44500
|
+
const target = ev.target;
|
|
44501
|
+
if (target !== document.activeElement) {
|
|
44502
|
+
target.focus();
|
|
44503
|
+
target.select();
|
|
44504
|
+
ev.preventDefault();
|
|
44505
|
+
ev.stopPropagation();
|
|
44506
|
+
}
|
|
44325
44507
|
}
|
|
44326
44508
|
}
|
|
44327
44509
|
|
|
@@ -44874,7 +45056,16 @@ class PivotTitleSection extends Component {
|
|
|
44874
45056
|
newPivotId,
|
|
44875
45057
|
newSheetId,
|
|
44876
45058
|
});
|
|
44877
|
-
|
|
45059
|
+
let text;
|
|
45060
|
+
if (result.isSuccessful) {
|
|
45061
|
+
text = _t("Pivot duplicated.");
|
|
45062
|
+
}
|
|
45063
|
+
else if (result.isCancelledBecause("PivotInError" /* CommandResult.PivotInError */)) {
|
|
45064
|
+
text = _t("Cannot duplicate a pivot in error.");
|
|
45065
|
+
}
|
|
45066
|
+
else {
|
|
45067
|
+
text = _t("Pivot duplication failed.");
|
|
45068
|
+
}
|
|
44878
45069
|
const type = result.isSuccessful ? "success" : "danger";
|
|
44879
45070
|
this.env.notifyUser({
|
|
44880
45071
|
text,
|
|
@@ -46025,12 +46216,10 @@ class SpreadsheetPivot {
|
|
|
46025
46216
|
* Take cares of double names
|
|
46026
46217
|
*/
|
|
46027
46218
|
findName(name, fields) {
|
|
46028
|
-
|
|
46029
|
-
|
|
46030
|
-
|
|
46031
|
-
|
|
46032
|
-
}
|
|
46033
|
-
return name;
|
|
46219
|
+
return getUniqueText(name, Object.keys(fields), {
|
|
46220
|
+
compute: (name, i) => `${name}${i}`,
|
|
46221
|
+
start: 2,
|
|
46222
|
+
});
|
|
46034
46223
|
}
|
|
46035
46224
|
extractDataEntriesFromRange(range) {
|
|
46036
46225
|
const dataEntries = [];
|
|
@@ -46213,7 +46402,9 @@ class PivotSidePanelStore extends SpreadsheetStore {
|
|
|
46213
46402
|
pivot: this.draft,
|
|
46214
46403
|
});
|
|
46215
46404
|
this.draft = null;
|
|
46216
|
-
if (!this.alreadyNotified &&
|
|
46405
|
+
if (!this.alreadyNotified &&
|
|
46406
|
+
!this.isDynamicPivotInViewport() &&
|
|
46407
|
+
this.isStaticPivotInViewport()) {
|
|
46217
46408
|
const formulaId = this.getters.getPivotFormulaId(this.pivotId);
|
|
46218
46409
|
const pivotExample = `=PIVOT(${formulaId})`;
|
|
46219
46410
|
this.alreadyNotified = true;
|
|
@@ -46270,11 +46461,20 @@ class PivotSidePanelStore extends SpreadsheetStore {
|
|
|
46270
46461
|
}
|
|
46271
46462
|
}
|
|
46272
46463
|
isDynamicPivotInViewport() {
|
|
46273
|
-
const
|
|
46274
|
-
|
|
46275
|
-
|
|
46276
|
-
|
|
46277
|
-
|
|
46464
|
+
for (const position of this.getters.getVisibleCellPositions()) {
|
|
46465
|
+
const isDynamicPivot = this.getters.isSpillPivotFormula(position);
|
|
46466
|
+
if (isDynamicPivot) {
|
|
46467
|
+
return true;
|
|
46468
|
+
}
|
|
46469
|
+
}
|
|
46470
|
+
return false;
|
|
46471
|
+
}
|
|
46472
|
+
isStaticPivotInViewport() {
|
|
46473
|
+
for (const position of this.getters.getVisibleCellPositions()) {
|
|
46474
|
+
const cell = this.getters.getCell(position);
|
|
46475
|
+
if (cell?.isFormula) {
|
|
46476
|
+
const pivotFunction = getFirstPivotFunction(cell.compiledFormula.tokens);
|
|
46477
|
+
if (pivotFunction && pivotFunction.functionName !== "PIVOT") {
|
|
46278
46478
|
return true;
|
|
46279
46479
|
}
|
|
46280
46480
|
}
|
|
@@ -51693,7 +51893,7 @@ class Grid extends Component {
|
|
|
51693
51893
|
this.cellPopovers = useStore(CellPopoverStore);
|
|
51694
51894
|
useEffect(() => {
|
|
51695
51895
|
if (!this.sidePanel.isOpen) {
|
|
51696
|
-
this.DOMFocusableElementStore.focus();
|
|
51896
|
+
this.DOMFocusableElementStore.focusableElement?.focus();
|
|
51697
51897
|
}
|
|
51698
51898
|
}, () => [this.sidePanel.isOpen]);
|
|
51699
51899
|
}
|
|
@@ -51899,7 +52099,7 @@ class Grid extends Component {
|
|
|
51899
52099
|
focusDefaultElement() {
|
|
51900
52100
|
if (!this.env.model.getters.getSelectedFigureId() &&
|
|
51901
52101
|
this.composerFocusStore.activeComposer.editionMode === "inactive") {
|
|
51902
|
-
this.DOMFocusableElementStore.focus();
|
|
52102
|
+
this.DOMFocusableElementStore.focusableElement?.focus();
|
|
51903
52103
|
}
|
|
51904
52104
|
}
|
|
51905
52105
|
get gridEl() {
|
|
@@ -52258,15 +52458,11 @@ class Grid extends Component {
|
|
|
52258
52458
|
class BasePlugin {
|
|
52259
52459
|
static getters = [];
|
|
52260
52460
|
history;
|
|
52261
|
-
|
|
52262
|
-
canDispatch;
|
|
52263
|
-
constructor(stateObserver, dispatch, canDispatch) {
|
|
52461
|
+
constructor(stateObserver) {
|
|
52264
52462
|
this.history = Object.assign(Object.create(stateObserver), {
|
|
52265
52463
|
update: stateObserver.addChange.bind(stateObserver, this),
|
|
52266
52464
|
selectCell: () => { },
|
|
52267
52465
|
});
|
|
52268
|
-
this.dispatch = dispatch;
|
|
52269
|
-
this.canDispatch = canDispatch;
|
|
52270
52466
|
}
|
|
52271
52467
|
/**
|
|
52272
52468
|
* Export for excel should be available for all plugins, even for the UI.
|
|
@@ -52344,10 +52540,14 @@ class BasePlugin {
|
|
|
52344
52540
|
*/
|
|
52345
52541
|
class CorePlugin extends BasePlugin {
|
|
52346
52542
|
getters;
|
|
52543
|
+
dispatch;
|
|
52544
|
+
canDispatch;
|
|
52347
52545
|
constructor({ getters, stateObserver, range, dispatch, canDispatch }) {
|
|
52348
|
-
super(stateObserver
|
|
52546
|
+
super(stateObserver);
|
|
52349
52547
|
range.addRangeProvider(this.adaptRanges.bind(this));
|
|
52350
52548
|
this.getters = getters;
|
|
52549
|
+
this.dispatch = dispatch;
|
|
52550
|
+
this.canDispatch = canDispatch;
|
|
52351
52551
|
}
|
|
52352
52552
|
// ---------------------------------------------------------------------------
|
|
52353
52553
|
// Import/Export
|
|
@@ -52436,10 +52636,34 @@ class BordersPlugin extends CorePlugin {
|
|
|
52436
52636
|
const elements = [...cmd.elements].sort((a, b) => b - a);
|
|
52437
52637
|
for (const group of groupConsecutive(elements)) {
|
|
52438
52638
|
if (cmd.dimension === "COL") {
|
|
52439
|
-
|
|
52639
|
+
if (group[0] >= this.getters.getNumberCols(cmd.sheetId)) {
|
|
52640
|
+
for (let row = 0; row < this.getters.getNumberRows(cmd.sheetId); row++) {
|
|
52641
|
+
this.history.update("borders", cmd.sheetId, group[0] + 1, row, "vertical", undefined);
|
|
52642
|
+
}
|
|
52643
|
+
}
|
|
52644
|
+
if (group[group.length - 1] === 0) {
|
|
52645
|
+
for (let row = 0; row < this.getters.getNumberRows(cmd.sheetId); row++) {
|
|
52646
|
+
this.history.update("borders", cmd.sheetId, 0, row, "vertical", undefined);
|
|
52647
|
+
}
|
|
52648
|
+
}
|
|
52649
|
+
const zone = this.getters.getColsZone(cmd.sheetId, group[group.length - 1] + 1, group[0]);
|
|
52650
|
+
this.clearInsideBorders(cmd.sheetId, [zone]);
|
|
52651
|
+
this.shiftBordersHorizontally(cmd.sheetId, group[0] + 1, -group.length);
|
|
52440
52652
|
}
|
|
52441
52653
|
else {
|
|
52442
|
-
|
|
52654
|
+
if (group[0] >= this.getters.getNumberRows(cmd.sheetId)) {
|
|
52655
|
+
for (let col = 0; col < this.getters.getNumberCols(cmd.sheetId); col++) {
|
|
52656
|
+
this.history.update("borders", cmd.sheetId, col, group[0] + 1, "horizontal", undefined);
|
|
52657
|
+
}
|
|
52658
|
+
}
|
|
52659
|
+
if (group[group.length - 1] === 0) {
|
|
52660
|
+
for (let col = 0; col < this.getters.getNumberCols(cmd.sheetId); col++) {
|
|
52661
|
+
this.history.update("borders", cmd.sheetId, col, 0, "horizontal", undefined);
|
|
52662
|
+
}
|
|
52663
|
+
}
|
|
52664
|
+
const zone = this.getters.getRowsZone(cmd.sheetId, group[group.length - 1] + 1, group[0]);
|
|
52665
|
+
this.clearInsideBorders(cmd.sheetId, [zone]);
|
|
52666
|
+
this.shiftBordersVertically(cmd.sheetId, group[0] + 1, -group.length);
|
|
52443
52667
|
}
|
|
52444
52668
|
}
|
|
52445
52669
|
break;
|
|
@@ -52746,6 +52970,18 @@ class BordersPlugin extends CorePlugin {
|
|
|
52746
52970
|
}
|
|
52747
52971
|
}
|
|
52748
52972
|
}
|
|
52973
|
+
/**
|
|
52974
|
+
* Remove the borders inside of a zone
|
|
52975
|
+
*/
|
|
52976
|
+
clearInsideBorders(sheetId, zones) {
|
|
52977
|
+
for (let zone of zones) {
|
|
52978
|
+
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
52979
|
+
for (let col = zone.left; col <= zone.right; col++) {
|
|
52980
|
+
this.history.update("borders", sheetId, col, row, undefined);
|
|
52981
|
+
}
|
|
52982
|
+
}
|
|
52983
|
+
}
|
|
52984
|
+
}
|
|
52749
52985
|
/**
|
|
52750
52986
|
* Add a border to the existing one to a cell
|
|
52751
52987
|
*/
|
|
@@ -53548,7 +53784,7 @@ class ChartPlugin extends CorePlugin {
|
|
|
53548
53784
|
if (fig.tag === "chart") {
|
|
53549
53785
|
const figureIdBase = fig.id.split(FIGURE_ID_SPLITTER).pop();
|
|
53550
53786
|
const duplicatedFigureId = `${cmd.sheetIdTo}${FIGURE_ID_SPLITTER}${figureIdBase}`;
|
|
53551
|
-
const chart = this.charts[fig.id]?.
|
|
53787
|
+
const chart = this.charts[fig.id]?.duplicateInDuplicatedSheet(cmd.sheetIdTo);
|
|
53552
53788
|
if (chart) {
|
|
53553
53789
|
this.dispatch("CREATE_CHART", {
|
|
53554
53790
|
id: duplicatedFigureId,
|
|
@@ -54192,7 +54428,7 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
54192
54428
|
case "DUPLICATE_SHEET": {
|
|
54193
54429
|
const rules = deepCopy(this.rules[cmd.sheetId]).map((rule) => ({
|
|
54194
54430
|
...rule,
|
|
54195
|
-
ranges: rule.ranges.map((range) =>
|
|
54431
|
+
ranges: rule.ranges.map((range) => duplicateRangeInDuplicatedSheet(cmd.sheetId, cmd.sheetIdTo, range)),
|
|
54196
54432
|
}));
|
|
54197
54433
|
this.history.update("rules", cmd.sheetIdTo, rules);
|
|
54198
54434
|
break;
|
|
@@ -56241,14 +56477,11 @@ class SheetPlugin extends CorePlugin {
|
|
|
56241
56477
|
return dimension === "COL" ? this.getNumberCols(sheetId) : this.getNumberRows(sheetId);
|
|
56242
56478
|
}
|
|
56243
56479
|
getNextSheetName(baseName = "Sheet") {
|
|
56244
|
-
let i = 1;
|
|
56245
56480
|
const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
|
|
56246
|
-
|
|
56247
|
-
|
|
56248
|
-
|
|
56249
|
-
|
|
56250
|
-
}
|
|
56251
|
-
return name;
|
|
56481
|
+
return getUniqueText(baseName, names, {
|
|
56482
|
+
compute: (name, i) => `${name}${i}`,
|
|
56483
|
+
computeFirstOne: true,
|
|
56484
|
+
});
|
|
56252
56485
|
}
|
|
56253
56486
|
getSheetSize(sheetId) {
|
|
56254
56487
|
return {
|
|
@@ -56528,15 +56761,9 @@ class SheetPlugin extends CorePlugin {
|
|
|
56528
56761
|
this.history.update("sheetIdsMapName", sheetIdsMapName);
|
|
56529
56762
|
}
|
|
56530
56763
|
getDuplicateSheetName(sheetName) {
|
|
56531
|
-
let i = 1;
|
|
56532
56764
|
const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
|
|
56533
56765
|
const baseName = _t("Copy of %s", sheetName);
|
|
56534
|
-
|
|
56535
|
-
while (names.includes(name)) {
|
|
56536
|
-
name = `${baseName} (${i})`;
|
|
56537
|
-
i++;
|
|
56538
|
-
}
|
|
56539
|
-
return name;
|
|
56766
|
+
return getUniqueText(baseName.toString(), names);
|
|
56540
56767
|
}
|
|
56541
56768
|
deleteSheet(sheet) {
|
|
56542
56769
|
const name = sheet.name;
|
|
@@ -58066,15 +58293,8 @@ class TableStylePlugin extends CorePlugin {
|
|
|
58066
58293
|
}
|
|
58067
58294
|
getNewCustomTableStyleName() {
|
|
58068
58295
|
let name = _t("Custom Table Style");
|
|
58069
|
-
const styleNames =
|
|
58070
|
-
|
|
58071
|
-
return name;
|
|
58072
|
-
}
|
|
58073
|
-
let i = 2;
|
|
58074
|
-
while (styleNames.has(`${name} ${i}`)) {
|
|
58075
|
-
i++;
|
|
58076
|
-
}
|
|
58077
|
-
return `${name} ${i}`;
|
|
58296
|
+
const styleNames = Object.values(this.styles).map((style) => style.displayName);
|
|
58297
|
+
return getUniqueText(name, styleNames, { compute: (name, i) => `${name} ${i}`, start: 2 });
|
|
58078
58298
|
}
|
|
58079
58299
|
isTableStyleEditable(styleId) {
|
|
58080
58300
|
return !TABLE_PRESETS[styleId];
|
|
@@ -58104,24 +58324,15 @@ class TableStylePlugin extends CorePlugin {
|
|
|
58104
58324
|
}
|
|
58105
58325
|
|
|
58106
58326
|
/**
|
|
58107
|
-
*
|
|
58108
|
-
* They
|
|
58327
|
+
* Core view plugins handle any data derived from core date (i.e. evaluation).
|
|
58328
|
+
* They cannot impact the model data (i.e. cannot dispatch commands).
|
|
58109
58329
|
*/
|
|
58110
|
-
class
|
|
58111
|
-
static layers = [];
|
|
58330
|
+
class CoreViewPlugin extends BasePlugin {
|
|
58112
58331
|
getters;
|
|
58113
|
-
|
|
58114
|
-
|
|
58115
|
-
constructor({ getters, stateObserver, dispatch, canDispatch, uiActions, selection, }) {
|
|
58116
|
-
super(stateObserver, dispatch, canDispatch);
|
|
58332
|
+
constructor({ getters, stateObserver }) {
|
|
58333
|
+
super(stateObserver);
|
|
58117
58334
|
this.getters = getters;
|
|
58118
|
-
this.ui = uiActions;
|
|
58119
|
-
this.selection = selection;
|
|
58120
58335
|
}
|
|
58121
|
-
// ---------------------------------------------------------------------------
|
|
58122
|
-
// Grid rendering
|
|
58123
|
-
// ---------------------------------------------------------------------------
|
|
58124
|
-
drawLayer(ctx, layer) { }
|
|
58125
58336
|
}
|
|
58126
58337
|
|
|
58127
58338
|
/**
|
|
@@ -59816,7 +60027,7 @@ function updateEvalContextAndExecute(compiledFormula, compilationParams, sheetId
|
|
|
59816
60027
|
// as necessary in several iterations, where evaluated cells can trigger the evaluation
|
|
59817
60028
|
// of other cells depending on it, at the next iteration.
|
|
59818
60029
|
//#endregion
|
|
59819
|
-
class EvaluationPlugin extends
|
|
60030
|
+
class EvaluationPlugin extends CoreViewPlugin {
|
|
59820
60031
|
static getters = [
|
|
59821
60032
|
"evaluateFormula",
|
|
59822
60033
|
"evaluateFormulaResult",
|
|
@@ -60083,7 +60294,7 @@ function colorDistance(color1, color2) {
|
|
|
60083
60294
|
* This plugins aims to compute and keep to custom colors used in the
|
|
60084
60295
|
* current spreadsheet
|
|
60085
60296
|
*/
|
|
60086
|
-
class CustomColorsPlugin extends
|
|
60297
|
+
class CustomColorsPlugin extends CoreViewPlugin {
|
|
60087
60298
|
customColors = {};
|
|
60088
60299
|
shouldUpdateColors = true;
|
|
60089
60300
|
static getters = ["getCustomColors"];
|
|
@@ -60219,7 +60430,7 @@ class CustomColorsPlugin extends UIPlugin {
|
|
|
60219
60430
|
}
|
|
60220
60431
|
}
|
|
60221
60432
|
|
|
60222
|
-
class EvaluationChartPlugin extends
|
|
60433
|
+
class EvaluationChartPlugin extends CoreViewPlugin {
|
|
60223
60434
|
static getters = ["getChartRuntime", "getStyleOfSingleCellChart"];
|
|
60224
60435
|
charts = {};
|
|
60225
60436
|
createRuntimeChart = chartRuntimeFactory(this.getters);
|
|
@@ -60323,7 +60534,7 @@ class EvaluationChartPlugin extends UIPlugin {
|
|
|
60323
60534
|
}
|
|
60324
60535
|
}
|
|
60325
60536
|
|
|
60326
|
-
class EvaluationConditionalFormatPlugin extends
|
|
60537
|
+
class EvaluationConditionalFormatPlugin extends CoreViewPlugin {
|
|
60327
60538
|
static getters = [
|
|
60328
60539
|
"getConditionalIcon",
|
|
60329
60540
|
"getCellConditionalFormatStyle",
|
|
@@ -60641,7 +60852,7 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
|
|
|
60641
60852
|
}
|
|
60642
60853
|
|
|
60643
60854
|
const VALID_RESULT = { isValid: true };
|
|
60644
|
-
class EvaluationDataValidationPlugin extends
|
|
60855
|
+
class EvaluationDataValidationPlugin extends CoreViewPlugin {
|
|
60645
60856
|
static getters = [
|
|
60646
60857
|
"getDataValidationInvalidCriterionValueMessage",
|
|
60647
60858
|
"getInvalidDataValidationMessage",
|
|
@@ -60772,7 +60983,7 @@ class EvaluationDataValidationPlugin extends UIPlugin {
|
|
|
60772
60983
|
}
|
|
60773
60984
|
}
|
|
60774
60985
|
|
|
60775
|
-
class DynamicTablesPlugin extends
|
|
60986
|
+
class DynamicTablesPlugin extends CoreViewPlugin {
|
|
60776
60987
|
static getters = [
|
|
60777
60988
|
"canCreateDynamicTableOnZones",
|
|
60778
60989
|
"doesZonesContainFilter",
|
|
@@ -60946,7 +61157,7 @@ class DynamicTablesPlugin extends UIPlugin {
|
|
|
60946
61157
|
}
|
|
60947
61158
|
}
|
|
60948
61159
|
|
|
60949
|
-
class HeaderSizeUIPlugin extends
|
|
61160
|
+
class HeaderSizeUIPlugin extends CoreViewPlugin {
|
|
60950
61161
|
static getters = ["getRowSize", "getHeaderSize"];
|
|
60951
61162
|
tallestCellInRow = {};
|
|
60952
61163
|
ctx = document.createElement("canvas").getContext("2d");
|
|
@@ -61652,7 +61863,7 @@ const UNDO_REDO_PIVOT_COMMANDS = ["ADD_PIVOT", "UPDATE_PIVOT"];
|
|
|
61652
61863
|
function isPivotCommand(cmd) {
|
|
61653
61864
|
return UNDO_REDO_PIVOT_COMMANDS.includes(cmd.type);
|
|
61654
61865
|
}
|
|
61655
|
-
class PivotUIPlugin extends
|
|
61866
|
+
class PivotUIPlugin extends CoreViewPlugin {
|
|
61656
61867
|
static getters = [
|
|
61657
61868
|
"getPivot",
|
|
61658
61869
|
"getFirstPivotFunction",
|
|
@@ -61856,13 +62067,9 @@ class PivotUIPlugin extends UIPlugin {
|
|
|
61856
62067
|
}
|
|
61857
62068
|
generateNewCalculatedMeasureName(measures) {
|
|
61858
62069
|
const existingMeasures = measures.map((m) => m.fieldName);
|
|
61859
|
-
|
|
61860
|
-
|
|
61861
|
-
|
|
61862
|
-
i++;
|
|
61863
|
-
name = _t("Calculated measure %s", i);
|
|
61864
|
-
}
|
|
61865
|
-
return name;
|
|
62070
|
+
return getUniqueText(_t("Calculated measure 1"), existingMeasures, {
|
|
62071
|
+
compute: (name, i) => _t("Calculated measure %s", i),
|
|
62072
|
+
});
|
|
61866
62073
|
}
|
|
61867
62074
|
getPivot(pivotId) {
|
|
61868
62075
|
if (!this.getters.isExistingPivot(pivotId)) {
|
|
@@ -61916,6 +62123,31 @@ class PivotUIPlugin extends UIPlugin {
|
|
|
61916
62123
|
}
|
|
61917
62124
|
}
|
|
61918
62125
|
|
|
62126
|
+
/**
|
|
62127
|
+
* UI plugins handle any transient data required to display a spreadsheet.
|
|
62128
|
+
* They can draw on the grid canvas.
|
|
62129
|
+
*/
|
|
62130
|
+
class UIPlugin extends BasePlugin {
|
|
62131
|
+
static layers = [];
|
|
62132
|
+
getters;
|
|
62133
|
+
ui;
|
|
62134
|
+
selection;
|
|
62135
|
+
dispatch;
|
|
62136
|
+
canDispatch;
|
|
62137
|
+
constructor({ getters, stateObserver, dispatch, canDispatch, uiActions, selection, }) {
|
|
62138
|
+
super(stateObserver);
|
|
62139
|
+
this.getters = getters;
|
|
62140
|
+
this.ui = uiActions;
|
|
62141
|
+
this.selection = selection;
|
|
62142
|
+
this.dispatch = dispatch;
|
|
62143
|
+
this.canDispatch = canDispatch;
|
|
62144
|
+
}
|
|
62145
|
+
// ---------------------------------------------------------------------------
|
|
62146
|
+
// Grid rendering
|
|
62147
|
+
// ---------------------------------------------------------------------------
|
|
62148
|
+
drawLayer(ctx, layer) { }
|
|
62149
|
+
}
|
|
62150
|
+
|
|
61919
62151
|
/**
|
|
61920
62152
|
* This plugin manage the autofill.
|
|
61921
62153
|
*
|
|
@@ -63292,6 +63524,9 @@ class Session extends EventBus {
|
|
|
63292
63524
|
}
|
|
63293
63525
|
}
|
|
63294
63526
|
this.acknowledge(message);
|
|
63527
|
+
if (message.type === "REMOTE_REVISION" && message.clientId === this.clientId) {
|
|
63528
|
+
return;
|
|
63529
|
+
}
|
|
63295
63530
|
this.trigger("collaborative-event-received");
|
|
63296
63531
|
}
|
|
63297
63532
|
onClientMoved(message) {
|
|
@@ -63942,6 +64177,19 @@ class HeaderVisibilityUIPlugin extends UIPlugin {
|
|
|
63942
64177
|
|
|
63943
64178
|
class InsertPivotPlugin extends UIPlugin {
|
|
63944
64179
|
static getters = [];
|
|
64180
|
+
allowDispatch(cmd) {
|
|
64181
|
+
switch (cmd.type) {
|
|
64182
|
+
case "DUPLICATE_PIVOT_IN_NEW_SHEET":
|
|
64183
|
+
if (!this.getters.isExistingPivot(cmd.pivotId)) {
|
|
64184
|
+
return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
|
|
64185
|
+
}
|
|
64186
|
+
if (!this.getters.getPivot(cmd.pivotId).isValid()) {
|
|
64187
|
+
return "PivotInError" /* CommandResult.PivotInError */;
|
|
64188
|
+
}
|
|
64189
|
+
break;
|
|
64190
|
+
}
|
|
64191
|
+
return "Success" /* CommandResult.Success */;
|
|
64192
|
+
}
|
|
63945
64193
|
handle(cmd) {
|
|
63946
64194
|
switch (cmd.type) {
|
|
63947
64195
|
case "INSERT_NEW_PIVOT":
|
|
@@ -64015,15 +64263,9 @@ class InsertPivotPlugin extends UIPlugin {
|
|
|
64015
64263
|
}
|
|
64016
64264
|
}
|
|
64017
64265
|
getPivotDuplicateSheetName(pivotName) {
|
|
64018
|
-
let i = 1;
|
|
64019
64266
|
const names = this.getters.getSheetIds().map((id) => this.getters.getSheetName(id));
|
|
64020
64267
|
const sanitizedName = sanitizeSheetName(pivotName);
|
|
64021
|
-
|
|
64022
|
-
while (names.includes(name)) {
|
|
64023
|
-
name = `${sanitizedName} (${i})`;
|
|
64024
|
-
i++;
|
|
64025
|
-
}
|
|
64026
|
-
return name;
|
|
64268
|
+
return getUniqueText(sanitizedName, names);
|
|
64027
64269
|
}
|
|
64028
64270
|
insertPivotWithTable(sheetId, col, row, pivotId, table, mode) {
|
|
64029
64271
|
const { cols, rows, measures, fieldsType } = table;
|
|
@@ -66130,13 +66372,10 @@ class FilterEvaluationPlugin extends UIPlugin {
|
|
|
66130
66372
|
if (!colName) {
|
|
66131
66373
|
colName = `Column${colIndex}`;
|
|
66132
66374
|
}
|
|
66133
|
-
|
|
66134
|
-
|
|
66135
|
-
|
|
66136
|
-
|
|
66137
|
-
i++;
|
|
66138
|
-
}
|
|
66139
|
-
return currentColName;
|
|
66375
|
+
return getUniqueText(colName, usedColNames, {
|
|
66376
|
+
compute: (name, i) => colName + String(i),
|
|
66377
|
+
start: 2,
|
|
66378
|
+
});
|
|
66140
66379
|
}
|
|
66141
66380
|
}
|
|
66142
66381
|
|
|
@@ -68178,11 +68417,6 @@ class BottomBarSheet extends Component {
|
|
|
68178
68417
|
editionState = "initializing";
|
|
68179
68418
|
DOMFocusableElementStore;
|
|
68180
68419
|
setup() {
|
|
68181
|
-
onMounted(() => {
|
|
68182
|
-
if (this.isSheetActive) {
|
|
68183
|
-
this.scrollToSheet();
|
|
68184
|
-
}
|
|
68185
|
-
});
|
|
68186
68420
|
onPatched(() => {
|
|
68187
68421
|
if (this.sheetNameRef.el && this.state.isEditing && this.editionState === "initializing") {
|
|
68188
68422
|
this.editionState = "editing";
|
|
@@ -68191,6 +68425,11 @@ class BottomBarSheet extends Component {
|
|
|
68191
68425
|
});
|
|
68192
68426
|
this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
|
|
68193
68427
|
useExternalListener(window, "click", () => (this.state.pickerOpened = false));
|
|
68428
|
+
useEffect((sheetId) => {
|
|
68429
|
+
if (this.props.sheetId === sheetId) {
|
|
68430
|
+
this.scrollToSheet();
|
|
68431
|
+
}
|
|
68432
|
+
}, () => [this.env.model.getters.getActiveSheetId()]);
|
|
68194
68433
|
}
|
|
68195
68434
|
focusInputAndSelectContent() {
|
|
68196
68435
|
if (!this.state.isEditing || !this.sheetNameRef.el)
|
|
@@ -68202,7 +68441,10 @@ class BottomBarSheet extends Component {
|
|
|
68202
68441
|
}
|
|
68203
68442
|
}
|
|
68204
68443
|
scrollToSheet() {
|
|
68205
|
-
this.sheetDivRef.el?.scrollIntoView?.(
|
|
68444
|
+
this.sheetDivRef.el?.scrollIntoView?.({
|
|
68445
|
+
behavior: "smooth",
|
|
68446
|
+
inline: "nearest",
|
|
68447
|
+
});
|
|
68206
68448
|
}
|
|
68207
68449
|
onFocusOut() {
|
|
68208
68450
|
if (this.state.isEditing && this.editionState !== "initializing") {
|
|
@@ -68232,11 +68474,11 @@ class BottomBarSheet extends Component {
|
|
|
68232
68474
|
if (ev.key === "Enter") {
|
|
68233
68475
|
ev.preventDefault();
|
|
68234
68476
|
this.stopEdition();
|
|
68235
|
-
this.DOMFocusableElementStore.focus();
|
|
68477
|
+
this.DOMFocusableElementStore.focusableElement?.focus();
|
|
68236
68478
|
}
|
|
68237
68479
|
if (ev.key === "Escape") {
|
|
68238
68480
|
this.cancelEdition();
|
|
68239
|
-
this.DOMFocusableElementStore.focus();
|
|
68481
|
+
this.DOMFocusableElementStore.focusableElement?.focus();
|
|
68240
68482
|
}
|
|
68241
68483
|
}
|
|
68242
68484
|
onMouseEventSheetName(ev) {
|
|
@@ -68785,23 +69027,17 @@ class ClickableCellsStore extends SpreadsheetStore {
|
|
|
68785
69027
|
const cells = [];
|
|
68786
69028
|
const getters = this.getters;
|
|
68787
69029
|
const sheetId = getters.getActiveSheetId();
|
|
68788
|
-
for (const
|
|
68789
|
-
|
|
68790
|
-
|
|
68791
|
-
|
|
68792
|
-
continue;
|
|
68793
|
-
}
|
|
68794
|
-
const action = this.getClickableAction(position);
|
|
68795
|
-
if (!action) {
|
|
68796
|
-
continue;
|
|
68797
|
-
}
|
|
68798
|
-
const zone = getters.expandZone(sheetId, positionToZone(position));
|
|
68799
|
-
cells.push({
|
|
68800
|
-
coordinates: getters.getVisibleRect(zone),
|
|
68801
|
-
position,
|
|
68802
|
-
action,
|
|
68803
|
-
});
|
|
69030
|
+
for (const position of this.getters.getVisibleCellPositions()) {
|
|
69031
|
+
const action = this.getClickableAction(position);
|
|
69032
|
+
if (!action) {
|
|
69033
|
+
continue;
|
|
68804
69034
|
}
|
|
69035
|
+
const zone = getters.expandZone(sheetId, positionToZone(position));
|
|
69036
|
+
cells.push({
|
|
69037
|
+
coordinates: getters.getVisibleRect(zone),
|
|
69038
|
+
position,
|
|
69039
|
+
action,
|
|
69040
|
+
});
|
|
68805
69041
|
}
|
|
68806
69042
|
return cells;
|
|
68807
69043
|
}
|
|
@@ -73612,7 +73848,7 @@ function addRows(construct, data, sheet) {
|
|
|
73612
73848
|
if (content || styleId || formatId || borderId || value !== undefined) {
|
|
73613
73849
|
const attributes = [["r", xc]];
|
|
73614
73850
|
// style
|
|
73615
|
-
const id = normalizeStyle(construct, extractStyle(data, styleId, formatId, borderId));
|
|
73851
|
+
const id = normalizeStyle(construct, extractStyle(data, content, styleId, formatId, borderId));
|
|
73616
73852
|
// don't add style if default
|
|
73617
73853
|
if (id) {
|
|
73618
73854
|
attributes.push(["s", id]);
|
|
@@ -73966,7 +74202,12 @@ function createSharedStrings(strings) {
|
|
|
73966
74202
|
["count", strings.length],
|
|
73967
74203
|
["uniqueCount", strings.length],
|
|
73968
74204
|
];
|
|
73969
|
-
const stringNodes = strings.map((string) =>
|
|
74205
|
+
const stringNodes = strings.map((string) => {
|
|
74206
|
+
if (string.trim() !== string) {
|
|
74207
|
+
return escapeXml /*xml*/ `<si><t xml:space="preserve">${string}</t></si>`;
|
|
74208
|
+
}
|
|
74209
|
+
return escapeXml /*xml*/ `<si><t>${string}</t></si>`;
|
|
74210
|
+
});
|
|
73970
74211
|
const xml = escapeXml /*xml*/ `
|
|
73971
74212
|
<sst ${formatAttributes(namespaces)}>
|
|
73972
74213
|
${joinXmlNodes(stringNodes)}
|
|
@@ -74047,14 +74288,13 @@ function createRelRoot() {
|
|
|
74047
74288
|
*/
|
|
74048
74289
|
function fixLengthySheetNames(data) {
|
|
74049
74290
|
const nameMapping = {};
|
|
74050
|
-
const newNames =
|
|
74291
|
+
const newNames = [];
|
|
74051
74292
|
for (const sheet of data.sheets) {
|
|
74052
74293
|
let newName = sheet.name.slice(0, 31);
|
|
74053
|
-
|
|
74054
|
-
|
|
74055
|
-
|
|
74056
|
-
|
|
74057
|
-
newNames.add(newName);
|
|
74294
|
+
newName = getUniqueText(newName, newNames, {
|
|
74295
|
+
compute: (name, i) => name.slice(0, 31 - String(i).length) + i,
|
|
74296
|
+
});
|
|
74297
|
+
newNames.push(newName);
|
|
74058
74298
|
if (newName !== sheet.name) {
|
|
74059
74299
|
nameMapping[sheet.name] = newName;
|
|
74060
74300
|
sheet.name = newName;
|
|
@@ -74119,6 +74359,7 @@ class Model extends EventBus {
|
|
|
74119
74359
|
*/
|
|
74120
74360
|
config;
|
|
74121
74361
|
corePluginConfig;
|
|
74362
|
+
coreViewPluginConfig;
|
|
74122
74363
|
uiPluginConfig;
|
|
74123
74364
|
state;
|
|
74124
74365
|
selection;
|
|
@@ -74171,6 +74412,7 @@ class Model extends EventBus {
|
|
|
74171
74412
|
this.coreHandlers.push(this.range);
|
|
74172
74413
|
this.handlers.push(this.range);
|
|
74173
74414
|
this.corePluginConfig = this.setupCorePluginConfig();
|
|
74415
|
+
this.coreViewPluginConfig = this.setupCoreViewPluginConfig();
|
|
74174
74416
|
this.uiPluginConfig = this.setupUiPluginConfig();
|
|
74175
74417
|
// registering plugins
|
|
74176
74418
|
for (let Plugin of corePluginRegistry.getAll()) {
|
|
@@ -74179,7 +74421,7 @@ class Model extends EventBus {
|
|
|
74179
74421
|
Object.assign(this.getters, this.coreGetters);
|
|
74180
74422
|
this.session.loadInitialMessages(stateUpdateMessages);
|
|
74181
74423
|
for (let Plugin of coreViewsPluginRegistry.getAll()) {
|
|
74182
|
-
const plugin = this.
|
|
74424
|
+
const plugin = this.setupCoreViewPlugin(Plugin);
|
|
74183
74425
|
this.handlers.push(plugin);
|
|
74184
74426
|
this.uiHandlers.push(plugin);
|
|
74185
74427
|
this.coreHandlers.push(plugin);
|
|
@@ -74206,7 +74448,7 @@ class Model extends EventBus {
|
|
|
74206
74448
|
// events
|
|
74207
74449
|
this.setupSessionEvents();
|
|
74208
74450
|
this.joinSession();
|
|
74209
|
-
if (config.snapshotRequested) {
|
|
74451
|
+
if (config.snapshotRequested || (data["[Content_Types].xml"] && !this.getters.isReadonly())) {
|
|
74210
74452
|
const startSnapshot = performance.now();
|
|
74211
74453
|
console.debug("Snapshot requested");
|
|
74212
74454
|
this.session.snapshot(this.exportData());
|
|
@@ -74245,6 +74487,19 @@ class Model extends EventBus {
|
|
|
74245
74487
|
}
|
|
74246
74488
|
return plugin;
|
|
74247
74489
|
}
|
|
74490
|
+
setupCoreViewPlugin(Plugin) {
|
|
74491
|
+
const plugin = new Plugin(this.coreViewPluginConfig);
|
|
74492
|
+
for (let name of Plugin.getters) {
|
|
74493
|
+
if (!(name in plugin)) {
|
|
74494
|
+
throw new Error(`Invalid getter name: ${name} for plugin ${plugin.constructor}`);
|
|
74495
|
+
}
|
|
74496
|
+
if (name in this.getters) {
|
|
74497
|
+
throw new Error(`Getter "${name}" is already defined.`);
|
|
74498
|
+
}
|
|
74499
|
+
this.getters[name] = plugin[name].bind(plugin);
|
|
74500
|
+
}
|
|
74501
|
+
return plugin;
|
|
74502
|
+
}
|
|
74248
74503
|
/**
|
|
74249
74504
|
* Initialize and properly configure a plugin.
|
|
74250
74505
|
*
|
|
@@ -74346,6 +74601,20 @@ class Model extends EventBus {
|
|
|
74346
74601
|
external: this.config.external,
|
|
74347
74602
|
};
|
|
74348
74603
|
}
|
|
74604
|
+
setupCoreViewPluginConfig() {
|
|
74605
|
+
return {
|
|
74606
|
+
getters: this.getters,
|
|
74607
|
+
stateObserver: this.state,
|
|
74608
|
+
selection: this.selection,
|
|
74609
|
+
moveClient: this.session.move.bind(this.session),
|
|
74610
|
+
custom: this.config.custom,
|
|
74611
|
+
uiActions: this.config,
|
|
74612
|
+
session: this.session,
|
|
74613
|
+
defaultCurrency: this.config.defaultCurrency,
|
|
74614
|
+
customColors: this.config.customColors || [],
|
|
74615
|
+
external: this.config.external,
|
|
74616
|
+
};
|
|
74617
|
+
}
|
|
74349
74618
|
setupUiPluginConfig() {
|
|
74350
74619
|
return {
|
|
74351
74620
|
getters: this.getters,
|
|
@@ -74693,6 +74962,9 @@ const helpers = {
|
|
|
74693
74962
|
areDomainArgsFieldsValid,
|
|
74694
74963
|
splitReference,
|
|
74695
74964
|
sanitizeSheetName,
|
|
74965
|
+
getUniqueText,
|
|
74966
|
+
isNumber,
|
|
74967
|
+
isDateTime,
|
|
74696
74968
|
};
|
|
74697
74969
|
const links = {
|
|
74698
74970
|
isMarkdownLink,
|
|
@@ -74784,9 +75056,9 @@ const constants = {
|
|
|
74784
75056
|
};
|
|
74785
75057
|
const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
|
|
74786
75058
|
|
|
74787
|
-
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
75059
|
+
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
74788
75060
|
|
|
74789
75061
|
|
|
74790
|
-
__info__.version = "18.2.0-alpha.
|
|
74791
|
-
__info__.date = "
|
|
74792
|
-
__info__.hash = "
|
|
75062
|
+
__info__.version = "18.2.0-alpha.1";
|
|
75063
|
+
__info__.date = "2025-01-14T11:35:51.135Z";
|
|
75064
|
+
__info__.hash = "702f816";
|