@odoo/o-spreadsheet 18.1.0-alpha.5 → 18.1.0-alpha.7
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 +352 -316
- package/dist/o-spreadsheet.d.ts +367 -234
- package/dist/o-spreadsheet.esm.js +352 -316
- package/dist/o-spreadsheet.iife.js +352 -316
- package/dist/o-spreadsheet.iife.min.js +449 -449
- package/dist/o_spreadsheet.xml +33 -20
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 18.1.0-alpha.
|
|
6
|
-
* @date 2024-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.1.0-alpha.7
|
|
6
|
+
* @date 2024-12-05T10:40:26.512Z
|
|
7
|
+
* @hash 7b1c39b
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -172,10 +172,13 @@ const ALERT_INFO_BG = "#CDEDF1";
|
|
|
172
172
|
const ALERT_INFO_BORDER = "#98DBE2";
|
|
173
173
|
const ALERT_INFO_TEXT_COLOR = "#09414A";
|
|
174
174
|
const BADGE_SELECTED_COLOR = "#E6F2F3";
|
|
175
|
-
const
|
|
176
|
-
const
|
|
177
|
-
const
|
|
178
|
-
const
|
|
175
|
+
const CHART_PADDING$1 = 20;
|
|
176
|
+
const CHART_PADDING_BOTTOM = 10;
|
|
177
|
+
const CHART_PADDING_TOP = 15;
|
|
178
|
+
const CHART_TITLE_FONT_SIZE = 16;
|
|
179
|
+
const CHART_AXIS_TITLE_FONT_SIZE = 12;
|
|
180
|
+
const SCORECARD_CHART_TITLE_FONT_SIZE = 14;
|
|
181
|
+
const PIVOT_TOKEN_COLOR = "#F28C28";
|
|
179
182
|
// Color picker defaults as upper case HEX to match `toHex`helper
|
|
180
183
|
const COLOR_PICKER_DEFAULTS = [
|
|
181
184
|
"#000000",
|
|
@@ -335,8 +338,8 @@ const DEFAULT_WINDOW_SIZE = 2;
|
|
|
335
338
|
const DEBOUNCE_TIME = 200;
|
|
336
339
|
const MESSAGE_VERSION = 1;
|
|
337
340
|
// Sheets
|
|
338
|
-
const
|
|
339
|
-
const
|
|
341
|
+
const FORBIDDEN_SHEETNAME_CHARS = ["'", "*", "?", "/", "\\", "[", "]"];
|
|
342
|
+
const FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX = /'|\*|\?|\/|\\|\[|\]/;
|
|
340
343
|
// Cells
|
|
341
344
|
const FORMULA_REF_IDENTIFIER = "|";
|
|
342
345
|
// Components
|
|
@@ -389,6 +392,7 @@ const DEFAULT_CURRENCY = {
|
|
|
389
392
|
//------------------------------------------------------------------------------
|
|
390
393
|
// Miscellaneous
|
|
391
394
|
//------------------------------------------------------------------------------
|
|
395
|
+
const sanitizeSheetNameRegex = new RegExp(FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX, "g");
|
|
392
396
|
/**
|
|
393
397
|
* Remove quotes from a quoted string
|
|
394
398
|
* ```js
|
|
@@ -484,6 +488,10 @@ function getCanonicalSymbolName(symbolName) {
|
|
|
484
488
|
}
|
|
485
489
|
return symbolName;
|
|
486
490
|
}
|
|
491
|
+
/** Replace the excel-excluded characters of a sheetName */
|
|
492
|
+
function sanitizeSheetName(sheetName, replacementChar = " ") {
|
|
493
|
+
return sheetName.replace(sanitizeSheetNameRegex, replacementChar);
|
|
494
|
+
}
|
|
487
495
|
function clip(val, min, max) {
|
|
488
496
|
return val < min ? min : val > max ? max : val;
|
|
489
497
|
}
|
|
@@ -3498,7 +3506,9 @@ exports.CommandResult = void 0;
|
|
|
3498
3506
|
CommandResult["MaxInvalidFormula"] = "MaxInvalidFormula";
|
|
3499
3507
|
CommandResult["ValueUpperInvalidFormula"] = "ValueUpperInvalidFormula";
|
|
3500
3508
|
CommandResult["ValueLowerInvalidFormula"] = "ValueLowerInvalidFormula";
|
|
3509
|
+
CommandResult["InvalidSortAnchor"] = "InvalidSortAnchor";
|
|
3501
3510
|
CommandResult["InvalidSortZone"] = "InvalidSortZone";
|
|
3511
|
+
CommandResult["SortZoneWithArrayFormulas"] = "SortZoneWithArrayFormulas";
|
|
3502
3512
|
CommandResult["WaitingSessionConfirmation"] = "WaitingSessionConfirmation";
|
|
3503
3513
|
CommandResult["MergeOverlap"] = "MergeOverlap";
|
|
3504
3514
|
CommandResult["TooManyHiddenElements"] = "TooManyHiddenElements";
|
|
@@ -3554,7 +3564,6 @@ exports.CommandResult = void 0;
|
|
|
3554
3564
|
CommandResult["ValueCellIsInvalidFormula"] = "ValueCellIsInvalidFormula";
|
|
3555
3565
|
CommandResult["InvalidDefinition"] = "InvalidDefinition";
|
|
3556
3566
|
CommandResult["InvalidColor"] = "InvalidColor";
|
|
3557
|
-
CommandResult["DataBarRangeValuesMismatch"] = "DataBarRangeValuesMismatch";
|
|
3558
3567
|
})(exports.CommandResult || (exports.CommandResult = {}));
|
|
3559
3568
|
|
|
3560
3569
|
const DEFAULT_LOCALES = [
|
|
@@ -9515,6 +9524,12 @@ function chartFontColor(backgroundColor) {
|
|
|
9515
9524
|
}
|
|
9516
9525
|
return relativeLuminance(backgroundColor) < 0.3 ? "#FFFFFF" : "#000000";
|
|
9517
9526
|
}
|
|
9527
|
+
function chartMutedFontColor(backgroundColor) {
|
|
9528
|
+
if (!backgroundColor) {
|
|
9529
|
+
return "#666666";
|
|
9530
|
+
}
|
|
9531
|
+
return relativeLuminance(backgroundColor) < 0.3 ? "#C8C8C8" : "#666666";
|
|
9532
|
+
}
|
|
9518
9533
|
function checkDataset(definition) {
|
|
9519
9534
|
if (definition.dataSets) {
|
|
9520
9535
|
const invalidRanges = definition.dataSets.find((range) => !rangeReference.test(range.dataRange)) !== undefined;
|
|
@@ -9650,8 +9665,8 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
|
|
|
9650
9665
|
const yMin = chart.chartArea.top;
|
|
9651
9666
|
const textsPositions = {};
|
|
9652
9667
|
for (const dataset of chart._metasets) {
|
|
9653
|
-
if (dataset.xAxisID === TREND_LINE_XAXIS_ID) {
|
|
9654
|
-
|
|
9668
|
+
if (dataset.xAxisID === TREND_LINE_XAXIS_ID || dataset.hidden) {
|
|
9669
|
+
continue;
|
|
9655
9670
|
}
|
|
9656
9671
|
for (let i = 0; i < dataset._parsed.length; i++) {
|
|
9657
9672
|
const parsedValue = dataset._parsed[i];
|
|
@@ -10098,7 +10113,7 @@ let ScorecardChart$1 = class ScorecardChart extends AbstractChart {
|
|
|
10098
10113
|
function drawScoreChart(structure, canvas) {
|
|
10099
10114
|
const ctx = canvas.getContext("2d");
|
|
10100
10115
|
canvas.width = structure.canvas.width;
|
|
10101
|
-
const availableWidth = canvas.width -
|
|
10116
|
+
const availableWidth = canvas.width - CHART_PADDING$1 * 2;
|
|
10102
10117
|
canvas.height = structure.canvas.height;
|
|
10103
10118
|
ctx.fillStyle = structure.canvas.backgroundColor;
|
|
10104
10119
|
ctx.fillRect(0, 0, structure.canvas.width, structure.canvas.height);
|
|
@@ -10233,10 +10248,9 @@ function createScorecardChartRuntime(chart, getters) {
|
|
|
10233
10248
|
}
|
|
10234
10249
|
|
|
10235
10250
|
/* Padding at the border of the chart */
|
|
10236
|
-
const CHART_PADDING =
|
|
10251
|
+
const CHART_PADDING = 10;
|
|
10237
10252
|
const BOTTOM_PADDING_RATIO = 0.05;
|
|
10238
10253
|
/* Maximum font sizes of each element */
|
|
10239
|
-
const CHART_TITLE_FONT_SIZE = SCORECARD_GAUGE_CHART_FONT_SIZE;
|
|
10240
10254
|
const KEY_VALUE_FONT_SIZE = 32;
|
|
10241
10255
|
const BASELINE_MAX_FONT_SIZE = 16;
|
|
10242
10256
|
function formatBaselineDescr(baselineDescr, baseline) {
|
|
@@ -10308,7 +10322,7 @@ class ScorecardChartConfigBuilder {
|
|
|
10308
10322
|
: this.height - (this.height - titleHeight - baselineHeight) / 2 - CHART_PADDING,
|
|
10309
10323
|
},
|
|
10310
10324
|
};
|
|
10311
|
-
const minimalBaselinePosition = baselineArrowSize +
|
|
10325
|
+
const minimalBaselinePosition = baselineArrowSize + CHART_PADDING * 2;
|
|
10312
10326
|
if (structure.baseline.position.x < minimalBaselinePosition) {
|
|
10313
10327
|
structure.baseline.position.x = minimalBaselinePosition;
|
|
10314
10328
|
}
|
|
@@ -10388,7 +10402,7 @@ class ScorecardChartConfigBuilder {
|
|
|
10388
10402
|
return this.runtime.background;
|
|
10389
10403
|
}
|
|
10390
10404
|
get secondaryFontColor() {
|
|
10391
|
-
return
|
|
10405
|
+
return chartMutedFontColor(this.backgroundColor);
|
|
10392
10406
|
}
|
|
10393
10407
|
getTextDimensions(text, font) {
|
|
10394
10408
|
this.context.font = font;
|
|
@@ -10414,7 +10428,7 @@ class ScorecardChartConfigBuilder {
|
|
|
10414
10428
|
}
|
|
10415
10429
|
return {
|
|
10416
10430
|
title: {
|
|
10417
|
-
font: getDefaultContextFont(
|
|
10431
|
+
font: getDefaultContextFont(this.runtime.title.fontSize ?? SCORECARD_CHART_TITLE_FONT_SIZE, this.runtime.title.bold, this.runtime.title.italic),
|
|
10418
10432
|
color: this.runtime.title.color ?? this.secondaryFontColor,
|
|
10419
10433
|
},
|
|
10420
10434
|
keyValue: {
|
|
@@ -14671,7 +14685,6 @@ function sortCells(cells, sortDirection, emptyCellAsZero) {
|
|
|
14671
14685
|
return cellsToSort.sort(cellsSortingCriterion(sortDirection));
|
|
14672
14686
|
}
|
|
14673
14687
|
function interactiveSortSelection(env, sheetId, anchor, zone, sortDirection) {
|
|
14674
|
-
let result = DispatchResult.Success;
|
|
14675
14688
|
//several columns => bypass the contiguity check
|
|
14676
14689
|
let multiColumns = zone.right > zone.left;
|
|
14677
14690
|
if (env.model.getters.doesIntersectMerge(sheetId, zone)) {
|
|
@@ -14691,49 +14704,37 @@ function interactiveSortSelection(env, sheetId, anchor, zone, sortDirection) {
|
|
|
14691
14704
|
}
|
|
14692
14705
|
}
|
|
14693
14706
|
}
|
|
14694
|
-
const { col, row } = anchor;
|
|
14695
14707
|
if (multiColumns) {
|
|
14696
|
-
|
|
14708
|
+
interactiveSort(env, sheetId, anchor, zone, sortDirection);
|
|
14709
|
+
return;
|
|
14710
|
+
}
|
|
14711
|
+
const contiguousZone = env.model.getters.getContiguousZone(sheetId, zone);
|
|
14712
|
+
if (isEqual(contiguousZone, zone)) {
|
|
14713
|
+
interactiveSort(env, sheetId, anchor, zone, sortDirection);
|
|
14697
14714
|
}
|
|
14698
14715
|
else {
|
|
14699
|
-
|
|
14700
|
-
const contiguousZone = env.model.getters.getContiguousZone(sheetId, zone);
|
|
14701
|
-
if (isEqual(contiguousZone, zone)) {
|
|
14702
|
-
// merge as it is
|
|
14703
|
-
result = env.model.dispatch("SORT_CELLS", {
|
|
14704
|
-
sheetId,
|
|
14705
|
-
col,
|
|
14706
|
-
row,
|
|
14707
|
-
zone,
|
|
14708
|
-
sortDirection,
|
|
14709
|
-
});
|
|
14710
|
-
}
|
|
14711
|
-
else {
|
|
14712
|
-
env.askConfirmation(_t("We found data next to your selection. Since this data was not selected, it will not be sorted. Do you want to extend your selection?"), () => {
|
|
14713
|
-
zone = contiguousZone;
|
|
14714
|
-
result = env.model.dispatch("SORT_CELLS", {
|
|
14715
|
-
sheetId,
|
|
14716
|
-
col,
|
|
14717
|
-
row,
|
|
14718
|
-
zone,
|
|
14719
|
-
sortDirection,
|
|
14720
|
-
});
|
|
14721
|
-
}, () => {
|
|
14722
|
-
result = env.model.dispatch("SORT_CELLS", {
|
|
14723
|
-
sheetId,
|
|
14724
|
-
col,
|
|
14725
|
-
row,
|
|
14726
|
-
zone,
|
|
14727
|
-
sortDirection,
|
|
14728
|
-
});
|
|
14729
|
-
});
|
|
14730
|
-
}
|
|
14716
|
+
env.askConfirmation(_t("We found data next to your selection. Since this data was not selected, it will not be sorted. Do you want to extend your selection?"), () => interactiveSort(env, sheetId, anchor, contiguousZone, sortDirection), () => interactiveSort(env, sheetId, anchor, zone, sortDirection));
|
|
14731
14717
|
}
|
|
14718
|
+
}
|
|
14719
|
+
function interactiveSort(env, sheetId, anchor, zone, sortDirection, sortOptions) {
|
|
14720
|
+
const result = env.model.dispatch("SORT_CELLS", {
|
|
14721
|
+
sheetId,
|
|
14722
|
+
col: anchor.col,
|
|
14723
|
+
row: anchor.row,
|
|
14724
|
+
zone,
|
|
14725
|
+
sortDirection,
|
|
14726
|
+
sortOptions,
|
|
14727
|
+
});
|
|
14732
14728
|
if (result.isCancelledBecause("InvalidSortZone" /* CommandResult.InvalidSortZone */)) {
|
|
14733
14729
|
const { col, row } = anchor;
|
|
14734
14730
|
env.model.selection.selectZone({ cell: { col, row }, zone });
|
|
14735
14731
|
env.raiseError(_t("Cannot sort. To sort, select only cells or only merges that have the same size."));
|
|
14736
14732
|
}
|
|
14733
|
+
if (result.isCancelledBecause("SortZoneWithArrayFormulas" /* CommandResult.SortZoneWithArrayFormulas */)) {
|
|
14734
|
+
const { col, row } = anchor;
|
|
14735
|
+
env.model.selection.selectZone({ cell: { col, row }, zone });
|
|
14736
|
+
env.raiseError(_t("Cannot sort a zone with array formulas."));
|
|
14737
|
+
}
|
|
14737
14738
|
}
|
|
14738
14739
|
|
|
14739
14740
|
function sortMatrix(matrix, locale, ...criteria) {
|
|
@@ -21248,7 +21249,7 @@ function getFunctionsFromAST(ast, functionNames) {
|
|
|
21248
21249
|
|
|
21249
21250
|
const PIVOT_FUNCTIONS = ["PIVOT.VALUE", "PIVOT.HEADER", "PIVOT"];
|
|
21250
21251
|
/**
|
|
21251
|
-
* Create a proposal entry for the
|
|
21252
|
+
* Create a proposal entry for the composer autocomplete
|
|
21252
21253
|
* to insert a field name string in a formula.
|
|
21253
21254
|
*/
|
|
21254
21255
|
function makeFieldProposal(field, granularity) {
|
|
@@ -22031,14 +22032,8 @@ const GAUGE_PADDING_BOTTOM = 20;
|
|
|
22031
22032
|
const GAUGE_LABELS_FONT_SIZE = 12;
|
|
22032
22033
|
const GAUGE_DEFAULT_VALUE_FONT_SIZE = 80;
|
|
22033
22034
|
const GAUGE_BACKGROUND_COLOR = "#F3F2F1";
|
|
22034
|
-
const GAUGE_TEXT_COLOR = "#666666";
|
|
22035
|
-
const GAUGE_TEXT_COLOR_HIGH_CONTRAST = "#C8C8C8";
|
|
22036
|
-
const GAUGE_INFLECTION_MARKER_COLOR = "#666666aa";
|
|
22037
22035
|
const GAUGE_INFLECTION_LABEL_BOTTOM_MARGIN = 6;
|
|
22038
22036
|
const GAUGE_TITLE_SECTION_HEIGHT = 25;
|
|
22039
|
-
const GAUGE_TITLE_FONT_SIZE = SCORECARD_GAUGE_CHART_FONT_SIZE;
|
|
22040
|
-
const GAUGE_TITLE_PADDING_LEFT = SCORECARD_GAUGE_CHART_PADDING;
|
|
22041
|
-
const GAUGE_TITLE_PADDING_TOP = SCORECARD_GAUGE_CHART_PADDING;
|
|
22042
22037
|
function drawGaugeChart(canvas, runtime) {
|
|
22043
22038
|
const canvasBoundingRect = canvas.getBoundingClientRect();
|
|
22044
22039
|
canvas.width = canvasBoundingRect.width;
|
|
@@ -22097,7 +22092,7 @@ function drawInflectionValues(ctx, config) {
|
|
|
22097
22092
|
ctx.translate(rectX + width / 2 - 0.5, rectY + height - 0.5); // -0.5 for sharper lines. see RendererPlugin.drawBorders comment
|
|
22098
22093
|
ctx.rotate(Math.PI / 2 - inflectionValue.rotation);
|
|
22099
22094
|
ctx.lineWidth = 2;
|
|
22100
|
-
ctx.strokeStyle =
|
|
22095
|
+
ctx.strokeStyle = chartMutedFontColor(config.backgroundColor) + "aa";
|
|
22101
22096
|
ctx.beginPath();
|
|
22102
22097
|
ctx.moveTo(0, -(height - config.gauge.arcWidth));
|
|
22103
22098
|
ctx.lineTo(0, -height - 3);
|
|
@@ -22151,22 +22146,22 @@ function getGaugeRenderingConfig(boundingRect, runtime, ctx) {
|
|
|
22151
22146
|
x: gaugeRect.x + gaugeRect.width - gaugeArcWidth / 2,
|
|
22152
22147
|
y: gaugeRect.y + gaugeRect.height + GAUGE_LABELS_FONT_SIZE,
|
|
22153
22148
|
};
|
|
22154
|
-
const textColor =
|
|
22149
|
+
const textColor = chartMutedFontColor(runtime.background);
|
|
22155
22150
|
const inflectionValues = getInflectionValues(runtime, gaugeRect, textColor, ctx);
|
|
22156
22151
|
let x = 0, titleWidth = 0, titleHeight = 0;
|
|
22157
22152
|
if (runtime.title.text) {
|
|
22158
|
-
({ width: titleWidth, height: titleHeight } = computeTextDimension(ctx, runtime.title.text, { ...runtime.title
|
|
22153
|
+
({ width: titleWidth, height: titleHeight } = computeTextDimension(ctx, runtime.title.text, { fontSize: CHART_TITLE_FONT_SIZE, ...runtime.title }, "px"));
|
|
22159
22154
|
}
|
|
22160
22155
|
switch (runtime.title.align) {
|
|
22161
22156
|
case "right":
|
|
22162
|
-
x = boundingRect.width - titleWidth -
|
|
22157
|
+
x = boundingRect.width - titleWidth - CHART_PADDING$1;
|
|
22163
22158
|
break;
|
|
22164
22159
|
case "center":
|
|
22165
22160
|
x = (boundingRect.width - titleWidth) / 2;
|
|
22166
22161
|
break;
|
|
22167
22162
|
case "left":
|
|
22168
22163
|
default:
|
|
22169
|
-
x =
|
|
22164
|
+
x = CHART_PADDING$1;
|
|
22170
22165
|
break;
|
|
22171
22166
|
}
|
|
22172
22167
|
return {
|
|
@@ -22174,10 +22169,10 @@ function getGaugeRenderingConfig(boundingRect, runtime, ctx) {
|
|
|
22174
22169
|
height: boundingRect.height,
|
|
22175
22170
|
title: {
|
|
22176
22171
|
label: runtime.title.text ?? "",
|
|
22177
|
-
fontSize:
|
|
22172
|
+
fontSize: runtime.title.fontSize ?? CHART_TITLE_FONT_SIZE,
|
|
22178
22173
|
textPosition: {
|
|
22179
22174
|
x,
|
|
22180
|
-
y:
|
|
22175
|
+
y: CHART_PADDING_TOP + titleHeight / 2,
|
|
22181
22176
|
},
|
|
22182
22177
|
color: runtime.title.color ?? textColor,
|
|
22183
22178
|
bold: runtime.title.bold,
|
|
@@ -22294,11 +22289,6 @@ function getGaugeColor(runtime) {
|
|
|
22294
22289
|
}
|
|
22295
22290
|
return runtime.colors.at(-1);
|
|
22296
22291
|
}
|
|
22297
|
-
function getContrastedTextColor(backgroundColor) {
|
|
22298
|
-
return relativeLuminance(backgroundColor) > 0.3
|
|
22299
|
-
? GAUGE_TEXT_COLOR
|
|
22300
|
-
: GAUGE_TEXT_COLOR_HIGH_CONTRAST;
|
|
22301
|
-
}
|
|
22302
22292
|
function getSegmentsOfRectangle(rectangle) {
|
|
22303
22293
|
return [
|
|
22304
22294
|
{ start: rectangle.topLeft, end: rectangle.topRight },
|
|
@@ -27012,13 +27002,12 @@ migrationStepRegistry
|
|
|
27012
27002
|
versionFrom: "7",
|
|
27013
27003
|
migrate(data) {
|
|
27014
27004
|
const namesTaken = [];
|
|
27015
|
-
const globalForbiddenInExcel = new RegExp(FORBIDDEN_IN_EXCEL_REGEX, "g");
|
|
27016
27005
|
for (let sheet of data.sheets || []) {
|
|
27017
27006
|
if (!sheet.name) {
|
|
27018
27007
|
continue;
|
|
27019
27008
|
}
|
|
27020
27009
|
const oldName = sheet.name;
|
|
27021
|
-
const escapedName = oldName
|
|
27010
|
+
const escapedName = sanitizeSheetName(oldName, "_");
|
|
27022
27011
|
let i = 1;
|
|
27023
27012
|
let newName = escapedName;
|
|
27024
27013
|
while (namesTaken.includes(newName)) {
|
|
@@ -27721,7 +27710,6 @@ const CfTerms = {
|
|
|
27721
27710
|
["ValueLowerInvalidFormula" /* CommandResult.ValueLowerInvalidFormula */]: _t("Invalid lower inflection point formula"),
|
|
27722
27711
|
["EmptyRange" /* CommandResult.EmptyRange */]: _t("A range needs to be defined"),
|
|
27723
27712
|
["ValueCellIsInvalidFormula" /* CommandResult.ValueCellIsInvalidFormula */]: _t("At least one of the provided values is an invalid formula"),
|
|
27724
|
-
["DataBarRangeValuesMismatch" /* CommandResult.DataBarRangeValuesMismatch */]: _t("All the ranges and the range values must have the same size"),
|
|
27725
27713
|
Unexpected: _t("The rule is invalid for an unknown reason"),
|
|
27726
27714
|
},
|
|
27727
27715
|
ColorScale: _t("Color scale"),
|
|
@@ -28255,37 +28243,45 @@ function interpolateData(config, values, labels, newLabels) {
|
|
|
28255
28243
|
const labelRange = labelMax - labelMin;
|
|
28256
28244
|
const normalizedLabels = labels.map((v) => (v - labelMin) / labelRange);
|
|
28257
28245
|
const normalizedNewLabels = newLabels.map((v) => (v - labelMin) / labelRange);
|
|
28258
|
-
|
|
28259
|
-
|
|
28260
|
-
|
|
28261
|
-
|
|
28262
|
-
|
|
28263
|
-
|
|
28264
|
-
|
|
28265
|
-
|
|
28266
|
-
|
|
28267
|
-
|
|
28268
|
-
|
|
28269
|
-
|
|
28270
|
-
|
|
28271
|
-
|
|
28272
|
-
|
|
28273
|
-
|
|
28246
|
+
try {
|
|
28247
|
+
switch (config.type) {
|
|
28248
|
+
case "polynomial": {
|
|
28249
|
+
const order = config.order;
|
|
28250
|
+
if (!order) {
|
|
28251
|
+
return Array.from({ length: newLabels.length }, () => NaN);
|
|
28252
|
+
}
|
|
28253
|
+
if (order === 1) {
|
|
28254
|
+
return predictLinearValues([values], [normalizedLabels], [normalizedNewLabels], true)[0];
|
|
28255
|
+
}
|
|
28256
|
+
const coeffs = polynomialRegression(values, normalizedLabels, order, true).flat();
|
|
28257
|
+
return normalizedNewLabels.map((v) => evaluatePolynomial(coeffs, v, order));
|
|
28258
|
+
}
|
|
28259
|
+
case "exponential": {
|
|
28260
|
+
const positiveLogValues = [];
|
|
28261
|
+
const filteredLabels = [];
|
|
28262
|
+
for (let i = 0; i < values.length; i++) {
|
|
28263
|
+
if (values[i] > 0) {
|
|
28264
|
+
positiveLogValues.push(Math.log(values[i]));
|
|
28265
|
+
filteredLabels.push(normalizedLabels[i]);
|
|
28266
|
+
}
|
|
28267
|
+
}
|
|
28268
|
+
if (!filteredLabels.length) {
|
|
28269
|
+
return Array.from({ length: newLabels.length }, () => NaN);
|
|
28274
28270
|
}
|
|
28271
|
+
return expM(predictLinearValues([positiveLogValues], [filteredLabels], [normalizedNewLabels], true))[0];
|
|
28275
28272
|
}
|
|
28276
|
-
|
|
28277
|
-
return [];
|
|
28273
|
+
case "logarithmic": {
|
|
28274
|
+
return predictLinearValues([values], logM([normalizedLabels]), logM([normalizedNewLabels]), true)[0];
|
|
28278
28275
|
}
|
|
28279
|
-
|
|
28280
|
-
|
|
28281
|
-
|
|
28282
|
-
|
|
28283
|
-
|
|
28284
|
-
case "trailingMovingAverage": {
|
|
28285
|
-
return getMovingAverageValues(values, config.window);
|
|
28276
|
+
case "trailingMovingAverage": {
|
|
28277
|
+
return getMovingAverageValues(values, config.window);
|
|
28278
|
+
}
|
|
28279
|
+
default:
|
|
28280
|
+
return Array.from({ length: newLabels.length }, () => NaN);
|
|
28286
28281
|
}
|
|
28287
|
-
|
|
28288
|
-
|
|
28282
|
+
}
|
|
28283
|
+
catch (e) {
|
|
28284
|
+
return Array.from({ length: newLabels.length }, () => NaN);
|
|
28289
28285
|
}
|
|
28290
28286
|
}
|
|
28291
28287
|
function getChartAxisType(chart, labelRange, getters) {
|
|
@@ -28756,54 +28752,16 @@ function getChartColorsGenerator(definition, dataSetsSize) {
|
|
|
28756
28752
|
return new ColorGenerator(dataSetsSize, definition.dataSets?.map((ds) => ds.backgroundColor) || []);
|
|
28757
28753
|
}
|
|
28758
28754
|
|
|
28759
|
-
function
|
|
28760
|
-
// TODO FIXME: this is unused ATM. All the charts should probably use this instead oh whatever padding they are using now
|
|
28761
|
-
// also look into how DEFAULT_CHART_PADDING is used in scorecards, it look strange
|
|
28755
|
+
function getChartLayout(definition) {
|
|
28762
28756
|
return {
|
|
28763
28757
|
padding: {
|
|
28764
|
-
left:
|
|
28765
|
-
right:
|
|
28766
|
-
top:
|
|
28767
|
-
bottom:
|
|
28758
|
+
left: CHART_PADDING$1,
|
|
28759
|
+
right: CHART_PADDING$1,
|
|
28760
|
+
top: CHART_PADDING_TOP,
|
|
28761
|
+
bottom: CHART_PADDING_BOTTOM,
|
|
28768
28762
|
},
|
|
28769
28763
|
};
|
|
28770
28764
|
}
|
|
28771
|
-
function getBarChartLayout(definition) {
|
|
28772
|
-
return {
|
|
28773
|
-
padding: computeChartPadding({
|
|
28774
|
-
displayTitle: !!definition.title?.text,
|
|
28775
|
-
displayLegend: definition.legendPosition === "top",
|
|
28776
|
-
}),
|
|
28777
|
-
};
|
|
28778
|
-
}
|
|
28779
|
-
function getLineChartLayout(definition) {
|
|
28780
|
-
return {
|
|
28781
|
-
padding: computeChartPadding({
|
|
28782
|
-
displayTitle: !!definition.title?.text,
|
|
28783
|
-
displayLegend: definition.legendPosition === "top",
|
|
28784
|
-
}),
|
|
28785
|
-
};
|
|
28786
|
-
}
|
|
28787
|
-
function getPieChartLayout(definition) {
|
|
28788
|
-
return {
|
|
28789
|
-
padding: { left: 20, right: 20, top: definition.title ? 10 : 25, bottom: 10 },
|
|
28790
|
-
};
|
|
28791
|
-
}
|
|
28792
|
-
function getWaterfallChartLayout(definition) {
|
|
28793
|
-
return {
|
|
28794
|
-
padding: { left: 20, right: 20, top: definition.title ? 10 : 25, bottom: 10 },
|
|
28795
|
-
};
|
|
28796
|
-
}
|
|
28797
|
-
function computeChartPadding({ displayTitle, displayLegend, }) {
|
|
28798
|
-
let top = 25;
|
|
28799
|
-
if (displayTitle) {
|
|
28800
|
-
top = 0;
|
|
28801
|
-
}
|
|
28802
|
-
else if (displayLegend) {
|
|
28803
|
-
top = 10;
|
|
28804
|
-
}
|
|
28805
|
-
return { left: 20, right: 20, top, bottom: 10 };
|
|
28806
|
-
}
|
|
28807
28765
|
|
|
28808
28766
|
function getLegendDisplayOptions(definition, args) {
|
|
28809
28767
|
return {
|
|
@@ -28861,11 +28819,12 @@ function getScatterChartLegend(definition, args) {
|
|
|
28861
28819
|
return {
|
|
28862
28820
|
...INTERACTIVE_LEGEND_CONFIG,
|
|
28863
28821
|
...getLegendDisplayOptions(definition),
|
|
28864
|
-
|
|
28865
|
-
|
|
28866
|
-
|
|
28867
|
-
|
|
28868
|
-
|
|
28822
|
+
...getCustomLegendLabels(chartFontColor(definition.background), {
|
|
28823
|
+
pointStyle: "circle",
|
|
28824
|
+
// the stroke is the border around the circle, so increasing its size with the chart's color reduce the size of the circle
|
|
28825
|
+
strokeStyle: definition.background || "#ffffff",
|
|
28826
|
+
lineWidth: 8,
|
|
28827
|
+
}),
|
|
28869
28828
|
};
|
|
28870
28829
|
}
|
|
28871
28830
|
function getComboChartLegend(definition, args) {
|
|
@@ -28954,10 +28913,10 @@ const INTERACTIVE_LEGEND_CONFIG = {
|
|
|
28954
28913
|
target.style.cursor = "default";
|
|
28955
28914
|
},
|
|
28956
28915
|
onClick: (event, legendItem, legend) => {
|
|
28957
|
-
|
|
28916
|
+
const index = legendItem.datasetIndex;
|
|
28917
|
+
if (!legend.legendItems || index === undefined) {
|
|
28958
28918
|
return;
|
|
28959
28919
|
}
|
|
28960
|
-
const index = legend.legendItems.indexOf(legendItem);
|
|
28961
28920
|
if (legend.chart.isDatasetVisible(index)) {
|
|
28962
28921
|
legend.chart.hide(index);
|
|
28963
28922
|
}
|
|
@@ -28973,15 +28932,29 @@ function getCustomLegendLabels(fontColor, legendLabelConfig) {
|
|
|
28973
28932
|
labels: {
|
|
28974
28933
|
color: fontColor,
|
|
28975
28934
|
usePointStyle: true,
|
|
28976
|
-
generateLabels: (chart) => chart.data.datasets.map((dataset, index) =>
|
|
28977
|
-
|
|
28978
|
-
|
|
28979
|
-
|
|
28980
|
-
|
|
28981
|
-
|
|
28982
|
-
|
|
28983
|
-
|
|
28984
|
-
|
|
28935
|
+
generateLabels: (chart) => chart.data.datasets.map((dataset, index) => {
|
|
28936
|
+
if (dataset["xAxisID"] === TREND_LINE_XAXIS_ID) {
|
|
28937
|
+
return {
|
|
28938
|
+
text: dataset.label ?? "",
|
|
28939
|
+
fontColor,
|
|
28940
|
+
strokeStyle: dataset.borderColor,
|
|
28941
|
+
hidden: !chart.isDatasetVisible(index),
|
|
28942
|
+
pointStyle: "line",
|
|
28943
|
+
datasetIndex: index,
|
|
28944
|
+
lineWidth: 3,
|
|
28945
|
+
};
|
|
28946
|
+
}
|
|
28947
|
+
return {
|
|
28948
|
+
text: dataset.label ?? "",
|
|
28949
|
+
fontColor,
|
|
28950
|
+
strokeStyle: dataset.borderColor,
|
|
28951
|
+
fillStyle: dataset.backgroundColor,
|
|
28952
|
+
hidden: !chart.isDatasetVisible(index),
|
|
28953
|
+
pointStyle: dataset.type === "line" ? "line" : "rect",
|
|
28954
|
+
datasetIndex: index,
|
|
28955
|
+
...legendLabelConfig,
|
|
28956
|
+
};
|
|
28957
|
+
}),
|
|
28985
28958
|
},
|
|
28986
28959
|
};
|
|
28987
28960
|
}
|
|
@@ -29095,20 +29068,27 @@ function getWaterfallChartScales(definition, args) {
|
|
|
29095
29068
|
return scales;
|
|
29096
29069
|
}
|
|
29097
29070
|
function getPyramidChartScales(definition, args) {
|
|
29071
|
+
const { dataSetsValues } = args;
|
|
29098
29072
|
const scales = getBarChartScales(definition, args);
|
|
29099
29073
|
const scalesXCallback = scales.x.ticks.callback;
|
|
29100
29074
|
scales.x.ticks.callback = (value) => scalesXCallback(Math.abs(value));
|
|
29075
|
+
const maxValue = Math.max(...dataSetsValues.map((dataSet) => Math.max(...dataSet.data.map(Math.abs))));
|
|
29076
|
+
scales.x.suggestedMin = -maxValue;
|
|
29077
|
+
scales.x.suggestedMax = maxValue;
|
|
29101
29078
|
return scales;
|
|
29102
29079
|
}
|
|
29103
29080
|
function getRadarChartScales(definition, args) {
|
|
29104
|
-
const { locale, axisFormats } = args;
|
|
29081
|
+
const { locale, axisFormats, dataSetsValues } = args;
|
|
29082
|
+
const minValue = Math.min(...dataSetsValues.map((ds) => Math.min(...ds.data.filter((x) => !isNaN(x)))));
|
|
29105
29083
|
return {
|
|
29106
29084
|
r: {
|
|
29085
|
+
beginAtZero: true,
|
|
29107
29086
|
ticks: {
|
|
29108
29087
|
callback: formatTickValue({ format: axisFormats?.r, locale }),
|
|
29109
29088
|
backdropColor: definition.background || "#FFFFFF",
|
|
29110
29089
|
},
|
|
29111
29090
|
pointLabels: { color: chartFontColor(definition.background) },
|
|
29091
|
+
suggestedMin: minValue < 0 ? minValue - 1 : 0,
|
|
29112
29092
|
},
|
|
29113
29093
|
};
|
|
29114
29094
|
}
|
|
@@ -29122,6 +29102,7 @@ function getChartAxisTitleRuntime(design) {
|
|
|
29122
29102
|
font: {
|
|
29123
29103
|
style: italic ? "italic" : "normal",
|
|
29124
29104
|
weight: bold ? "bold" : "normal",
|
|
29105
|
+
size: design.title.fontSize ?? CHART_AXIS_TITLE_FONT_SIZE,
|
|
29125
29106
|
},
|
|
29126
29107
|
align: align === "left" ? "start" : align === "right" ? "end" : "center",
|
|
29127
29108
|
};
|
|
@@ -29187,17 +29168,22 @@ function getChartShowValues(definition, args) {
|
|
|
29187
29168
|
|
|
29188
29169
|
function getChartTitle(definition) {
|
|
29189
29170
|
const chartTitle = definition.title;
|
|
29190
|
-
const fontColor =
|
|
29171
|
+
const fontColor = chartMutedFontColor(definition.background);
|
|
29191
29172
|
return {
|
|
29192
29173
|
display: !!chartTitle.text,
|
|
29193
29174
|
text: _t(chartTitle.text),
|
|
29194
29175
|
color: chartTitle?.color ?? fontColor,
|
|
29195
29176
|
align: chartTitle.align === "center" ? "center" : chartTitle.align === "right" ? "end" : "start",
|
|
29196
29177
|
font: {
|
|
29197
|
-
size:
|
|
29178
|
+
size: definition.title.fontSize ?? CHART_TITLE_FONT_SIZE,
|
|
29198
29179
|
weight: chartTitle.bold ? "bold" : "normal",
|
|
29199
29180
|
style: chartTitle.italic ? "italic" : "normal",
|
|
29200
29181
|
},
|
|
29182
|
+
padding: {
|
|
29183
|
+
// Disable title top/left/right padding to use the chart padding instead.
|
|
29184
|
+
// The legend already has a top padding, so bottom padding is useless for the title there.
|
|
29185
|
+
bottom: definition.legendPosition === "top" ? 0 : CHART_PADDING$1,
|
|
29186
|
+
},
|
|
29201
29187
|
};
|
|
29202
29188
|
}
|
|
29203
29189
|
|
|
@@ -29344,26 +29330,23 @@ var CHART_RUNTIME_HELPERS = /*#__PURE__*/Object.freeze({
|
|
|
29344
29330
|
canChartParseLabels: canChartParseLabels,
|
|
29345
29331
|
getBarChartData: getBarChartData,
|
|
29346
29332
|
getBarChartDatasets: getBarChartDatasets,
|
|
29347
|
-
getBarChartLayout: getBarChartLayout,
|
|
29348
29333
|
getBarChartLegend: getBarChartLegend,
|
|
29349
29334
|
getBarChartScales: getBarChartScales,
|
|
29350
29335
|
getBarChartTooltip: getBarChartTooltip,
|
|
29351
29336
|
getChartLabelFormat: getChartLabelFormat,
|
|
29337
|
+
getChartLayout: getChartLayout,
|
|
29352
29338
|
getChartShowValues: getChartShowValues,
|
|
29353
29339
|
getChartTitle: getChartTitle,
|
|
29354
29340
|
getComboChartDatasets: getComboChartDatasets,
|
|
29355
29341
|
getComboChartLegend: getComboChartLegend,
|
|
29356
|
-
getCommonChartLayout: getCommonChartLayout,
|
|
29357
29342
|
getData: getData,
|
|
29358
29343
|
getLineChartData: getLineChartData,
|
|
29359
29344
|
getLineChartDatasets: getLineChartDatasets,
|
|
29360
|
-
getLineChartLayout: getLineChartLayout,
|
|
29361
29345
|
getLineChartLegend: getLineChartLegend,
|
|
29362
29346
|
getLineChartScales: getLineChartScales,
|
|
29363
29347
|
getLineChartTooltip: getLineChartTooltip,
|
|
29364
29348
|
getPieChartData: getPieChartData,
|
|
29365
29349
|
getPieChartDatasets: getPieChartDatasets,
|
|
29366
|
-
getPieChartLayout: getPieChartLayout,
|
|
29367
29350
|
getPieChartLegend: getPieChartLegend,
|
|
29368
29351
|
getPieChartTooltip: getPieChartTooltip,
|
|
29369
29352
|
getPyramidChartData: getPyramidChartData,
|
|
@@ -29379,7 +29362,6 @@ var CHART_RUNTIME_HELPERS = /*#__PURE__*/Object.freeze({
|
|
|
29379
29362
|
getScatterChartScales: getScatterChartScales,
|
|
29380
29363
|
getTrendDatasetForBarChart: getTrendDatasetForBarChart,
|
|
29381
29364
|
getTrendDatasetForLineChart: getTrendDatasetForLineChart,
|
|
29382
|
-
getWaterfallChartLayout: getWaterfallChartLayout,
|
|
29383
29365
|
getWaterfallChartLegend: getWaterfallChartLegend,
|
|
29384
29366
|
getWaterfallChartScales: getWaterfallChartScales,
|
|
29385
29367
|
getWaterfallChartTooltip: getWaterfallChartTooltip,
|
|
@@ -29527,7 +29509,7 @@ function createBarChartRuntime(chart, getters) {
|
|
|
29527
29509
|
options: {
|
|
29528
29510
|
...CHART_COMMON_OPTIONS,
|
|
29529
29511
|
indexAxis: chart.horizontal ? "y" : "x",
|
|
29530
|
-
layout:
|
|
29512
|
+
layout: getChartLayout(),
|
|
29531
29513
|
scales: getBarChartScales(definition, chartData),
|
|
29532
29514
|
plugins: {
|
|
29533
29515
|
title: getChartTitle(definition),
|
|
@@ -29679,7 +29661,7 @@ function createComboChartRuntime(chart, getters) {
|
|
|
29679
29661
|
},
|
|
29680
29662
|
options: {
|
|
29681
29663
|
...CHART_COMMON_OPTIONS,
|
|
29682
|
-
layout:
|
|
29664
|
+
layout: getChartLayout(),
|
|
29683
29665
|
scales: getBarChartScales(definition, chartData),
|
|
29684
29666
|
plugins: {
|
|
29685
29667
|
title: getChartTitle(definition),
|
|
@@ -30080,7 +30062,7 @@ function createLineChartRuntime(chart, getters) {
|
|
|
30080
30062
|
},
|
|
30081
30063
|
options: {
|
|
30082
30064
|
...CHART_COMMON_OPTIONS,
|
|
30083
|
-
layout:
|
|
30065
|
+
layout: getChartLayout(),
|
|
30084
30066
|
scales: getLineChartScales(definition, chartData),
|
|
30085
30067
|
plugins: {
|
|
30086
30068
|
title: getChartTitle(definition),
|
|
@@ -30215,7 +30197,7 @@ function createPieChartRuntime(chart, getters) {
|
|
|
30215
30197
|
},
|
|
30216
30198
|
options: {
|
|
30217
30199
|
...CHART_COMMON_OPTIONS,
|
|
30218
|
-
layout:
|
|
30200
|
+
layout: getChartLayout(),
|
|
30219
30201
|
plugins: {
|
|
30220
30202
|
title: getChartTitle(definition),
|
|
30221
30203
|
legend: getPieChartLegend(definition, chartData),
|
|
@@ -30352,7 +30334,7 @@ function createPyramidChartRuntime(chart, getters) {
|
|
|
30352
30334
|
options: {
|
|
30353
30335
|
...CHART_COMMON_OPTIONS,
|
|
30354
30336
|
indexAxis: "y",
|
|
30355
|
-
layout:
|
|
30337
|
+
layout: getChartLayout(),
|
|
30356
30338
|
scales: getPyramidChartScales(definition, chartData),
|
|
30357
30339
|
plugins: {
|
|
30358
30340
|
title: getChartTitle(definition),
|
|
@@ -30501,7 +30483,7 @@ function createRadarChartRuntime(chart, getters) {
|
|
|
30501
30483
|
},
|
|
30502
30484
|
options: {
|
|
30503
30485
|
...CHART_COMMON_OPTIONS,
|
|
30504
|
-
layout:
|
|
30486
|
+
layout: getChartLayout(),
|
|
30505
30487
|
scales: getRadarChartScales(definition, chartData),
|
|
30506
30488
|
plugins: {
|
|
30507
30489
|
title: getChartTitle(definition),
|
|
@@ -30654,7 +30636,7 @@ function createScatterChartRuntime(chart, getters) {
|
|
|
30654
30636
|
},
|
|
30655
30637
|
options: {
|
|
30656
30638
|
...CHART_COMMON_OPTIONS,
|
|
30657
|
-
layout:
|
|
30639
|
+
layout: getChartLayout(),
|
|
30658
30640
|
scales: getScatterChartScales(definition, chartData),
|
|
30659
30641
|
plugins: {
|
|
30660
30642
|
title: getChartTitle(definition),
|
|
@@ -30815,7 +30797,7 @@ function createWaterfallChartRuntime(chart, getters) {
|
|
|
30815
30797
|
},
|
|
30816
30798
|
options: {
|
|
30817
30799
|
...CHART_COMMON_OPTIONS,
|
|
30818
|
-
layout:
|
|
30800
|
+
layout: getChartLayout(),
|
|
30819
30801
|
scales: getWaterfallChartScales(definition, chartData),
|
|
30820
30802
|
plugins: {
|
|
30821
30803
|
title: getChartTitle(definition),
|
|
@@ -32209,14 +32191,9 @@ class FilterMenu extends owl.Component {
|
|
|
32209
32191
|
}
|
|
32210
32192
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
32211
32193
|
const contentZone = { ...tableZone, top: tableZone.top + 1 };
|
|
32212
|
-
|
|
32213
|
-
|
|
32214
|
-
|
|
32215
|
-
row: contentZone.top,
|
|
32216
|
-
zone: contentZone,
|
|
32217
|
-
sortDirection,
|
|
32218
|
-
sortOptions: { emptyCellAsZero: true, sortHeaders: true },
|
|
32219
|
-
});
|
|
32194
|
+
const sortAnchor = { col: filterPosition.col, row: contentZone.top };
|
|
32195
|
+
const sortOptions = { emptyCellAsZero: true, sortHeaders: true };
|
|
32196
|
+
interactiveSort(this.env, sheetId, sortAnchor, contentZone, sortDirection, sortOptions);
|
|
32220
32197
|
this.props.onClosed?.();
|
|
32221
32198
|
}
|
|
32222
32199
|
}
|
|
@@ -33130,6 +33107,7 @@ var CHART_HELPERS = /*#__PURE__*/Object.freeze({
|
|
|
33130
33107
|
adaptChartRange: adaptChartRange,
|
|
33131
33108
|
chartFactory: chartFactory,
|
|
33132
33109
|
chartFontColor: chartFontColor,
|
|
33110
|
+
chartMutedFontColor: chartMutedFontColor,
|
|
33133
33111
|
chartRuntimeFactory: chartRuntimeFactory,
|
|
33134
33112
|
chartToImage: chartToImage,
|
|
33135
33113
|
checkDataset: checkDataset,
|
|
@@ -34232,6 +34210,7 @@ const pivotProperties = {
|
|
|
34232
34210
|
const pivotId = env.model.getters.getPivotIdFromPosition(position);
|
|
34233
34211
|
return (pivotId && env.model.getters.isExistingPivot(pivotId)) || false;
|
|
34234
34212
|
},
|
|
34213
|
+
isReadonlyAllowed: true,
|
|
34235
34214
|
icon: "o-spreadsheet-Icon.PIVOT",
|
|
34236
34215
|
};
|
|
34237
34216
|
const FIX_FORMULAS = {
|
|
@@ -35949,6 +35928,7 @@ topbarMenuRegistry
|
|
|
35949
35928
|
id: `item_pivot_${env.model.getters.getPivotFormulaId(pivotId)}`,
|
|
35950
35929
|
name: env.model.getters.getPivotDisplayName(pivotId),
|
|
35951
35930
|
sequence: sequence + index,
|
|
35931
|
+
isReadonlyAllowed: true,
|
|
35952
35932
|
execute: (env) => env.openSidePanel("PivotSidePanel", { pivotId }),
|
|
35953
35933
|
onStartHover: (env) => env.getStore(HighlightStore).register(highlightProvider),
|
|
35954
35934
|
onStopHover: (env) => env.getStore(HighlightStore).unRegister(highlightProvider),
|
|
@@ -37420,6 +37400,95 @@ class ColorPickerWidget extends owl.Component {
|
|
|
37420
37400
|
}
|
|
37421
37401
|
}
|
|
37422
37402
|
|
|
37403
|
+
css /* scss */ `
|
|
37404
|
+
.o-font-size-editor {
|
|
37405
|
+
height: calc(100% - 4px);
|
|
37406
|
+
input.o-font-size {
|
|
37407
|
+
outline-color: ${SELECTION_BORDER_COLOR};
|
|
37408
|
+
height: 20px;
|
|
37409
|
+
width: 23px;
|
|
37410
|
+
}
|
|
37411
|
+
}
|
|
37412
|
+
.o-text-options > div {
|
|
37413
|
+
cursor: pointer;
|
|
37414
|
+
line-height: 26px;
|
|
37415
|
+
padding: 3px 12px;
|
|
37416
|
+
&:hover {
|
|
37417
|
+
background-color: rgba(0, 0, 0, 0.08);
|
|
37418
|
+
}
|
|
37419
|
+
}
|
|
37420
|
+
`;
|
|
37421
|
+
class FontSizeEditor extends owl.Component {
|
|
37422
|
+
static template = "o-spreadsheet-FontSizeEditor";
|
|
37423
|
+
static props = {
|
|
37424
|
+
currentFontSize: Number,
|
|
37425
|
+
onFontSizeChanged: Function,
|
|
37426
|
+
onToggle: { type: Function, optional: true },
|
|
37427
|
+
class: String,
|
|
37428
|
+
};
|
|
37429
|
+
static components = { Popover };
|
|
37430
|
+
fontSizes = FONT_SIZES;
|
|
37431
|
+
dropdown = owl.useState({ isOpen: false });
|
|
37432
|
+
inputRef = owl.useRef("inputFontSize");
|
|
37433
|
+
rootEditorRef = owl.useRef("FontSizeEditor");
|
|
37434
|
+
fontSizeListRef = owl.useRef("fontSizeList");
|
|
37435
|
+
setup() {
|
|
37436
|
+
owl.useExternalListener(window, "click", this.onExternalClick, { capture: true });
|
|
37437
|
+
}
|
|
37438
|
+
get popoverProps() {
|
|
37439
|
+
const { x, y, width, height } = this.rootEditorRef.el.getBoundingClientRect();
|
|
37440
|
+
return {
|
|
37441
|
+
anchorRect: { x, y, width, height },
|
|
37442
|
+
positioning: "BottomLeft",
|
|
37443
|
+
verticalOffset: 0,
|
|
37444
|
+
};
|
|
37445
|
+
}
|
|
37446
|
+
onExternalClick(ev) {
|
|
37447
|
+
if (!isChildEvent(this.fontSizeListRef.el, ev) && !isChildEvent(this.rootEditorRef.el, ev)) {
|
|
37448
|
+
this.closeFontList();
|
|
37449
|
+
}
|
|
37450
|
+
}
|
|
37451
|
+
toggleFontList() {
|
|
37452
|
+
const isOpen = this.dropdown.isOpen;
|
|
37453
|
+
if (!isOpen) {
|
|
37454
|
+
this.props.onToggle?.();
|
|
37455
|
+
this.inputRef.el.focus();
|
|
37456
|
+
}
|
|
37457
|
+
else {
|
|
37458
|
+
this.closeFontList();
|
|
37459
|
+
}
|
|
37460
|
+
}
|
|
37461
|
+
closeFontList() {
|
|
37462
|
+
this.dropdown.isOpen = false;
|
|
37463
|
+
}
|
|
37464
|
+
setSize(fontSizeStr) {
|
|
37465
|
+
const fontSize = clip(Math.floor(parseFloat(fontSizeStr)), 1, 400);
|
|
37466
|
+
this.props.onFontSizeChanged(fontSize);
|
|
37467
|
+
this.closeFontList();
|
|
37468
|
+
}
|
|
37469
|
+
setSizeFromInput(ev) {
|
|
37470
|
+
this.setSize(ev.target.value);
|
|
37471
|
+
}
|
|
37472
|
+
setSizeFromList(fontSizeStr) {
|
|
37473
|
+
this.setSize(fontSizeStr);
|
|
37474
|
+
}
|
|
37475
|
+
onInputFocused(ev) {
|
|
37476
|
+
this.dropdown.isOpen = true;
|
|
37477
|
+
ev.target.select();
|
|
37478
|
+
}
|
|
37479
|
+
onInputKeydown(ev) {
|
|
37480
|
+
if (ev.key === "Enter" || ev.key === "Escape") {
|
|
37481
|
+
this.closeFontList();
|
|
37482
|
+
const target = ev.target;
|
|
37483
|
+
// In the case of a ESCAPE key, we get the previous font size back
|
|
37484
|
+
if (ev.key === "Escape") {
|
|
37485
|
+
target.value = `${this.props.currentFontSize}`;
|
|
37486
|
+
}
|
|
37487
|
+
this.props.onToggle?.();
|
|
37488
|
+
}
|
|
37489
|
+
}
|
|
37490
|
+
}
|
|
37491
|
+
|
|
37423
37492
|
css /* scss */ `
|
|
37424
37493
|
.o-chart-title-designer {
|
|
37425
37494
|
> span {
|
|
@@ -37454,7 +37523,7 @@ css /* scss */ `
|
|
|
37454
37523
|
`;
|
|
37455
37524
|
class ChartTitle extends owl.Component {
|
|
37456
37525
|
static template = "o-spreadsheet.ChartTitle";
|
|
37457
|
-
static components = { Section, ColorPickerWidget };
|
|
37526
|
+
static components = { Section, ColorPickerWidget, FontSizeEditor };
|
|
37458
37527
|
static props = {
|
|
37459
37528
|
title: { type: String, optional: true },
|
|
37460
37529
|
updateTitle: Function,
|
|
@@ -37463,7 +37532,8 @@ class ChartTitle extends owl.Component {
|
|
|
37463
37532
|
toggleBold: { type: Function, optional: true },
|
|
37464
37533
|
updateAlignment: { type: Function, optional: true },
|
|
37465
37534
|
updateColor: { type: Function, optional: true },
|
|
37466
|
-
style:
|
|
37535
|
+
style: Object,
|
|
37536
|
+
onFontSizeChanged: Function,
|
|
37467
37537
|
};
|
|
37468
37538
|
static defaultProps = {
|
|
37469
37539
|
title: "",
|
|
@@ -37478,6 +37548,9 @@ class ChartTitle extends owl.Component {
|
|
|
37478
37548
|
updateTitle(ev) {
|
|
37479
37549
|
this.props.updateTitle(ev.target.value);
|
|
37480
37550
|
}
|
|
37551
|
+
updateFontSize(fontSize) {
|
|
37552
|
+
this.props.onFontSizeChanged(fontSize);
|
|
37553
|
+
}
|
|
37481
37554
|
toggleDropdownTool(tool, ev) {
|
|
37482
37555
|
const isOpen = this.state.activeTool === tool;
|
|
37483
37556
|
this.closeMenus();
|
|
@@ -37520,6 +37593,7 @@ class AxisDesignEditor extends owl.Component {
|
|
|
37520
37593
|
return {
|
|
37521
37594
|
color: "",
|
|
37522
37595
|
align: "center",
|
|
37596
|
+
fontSize: CHART_AXIS_TITLE_FONT_SIZE,
|
|
37523
37597
|
...axisDesign.title,
|
|
37524
37598
|
};
|
|
37525
37599
|
}
|
|
@@ -37537,6 +37611,17 @@ class AxisDesignEditor extends owl.Component {
|
|
|
37537
37611
|
};
|
|
37538
37612
|
this.props.updateChart(this.props.figureId, { axesDesign });
|
|
37539
37613
|
}
|
|
37614
|
+
updateAxisTitleFontSize(fontSize) {
|
|
37615
|
+
const axesDesign = this.props.definition.axesDesign ?? {};
|
|
37616
|
+
axesDesign[this.state.currentAxis] = {
|
|
37617
|
+
...axesDesign[this.state.currentAxis],
|
|
37618
|
+
title: {
|
|
37619
|
+
...(axesDesign[this.state.currentAxis]?.title ?? {}),
|
|
37620
|
+
fontSize,
|
|
37621
|
+
},
|
|
37622
|
+
};
|
|
37623
|
+
this.props.updateChart(this.props.figureId, { axesDesign });
|
|
37624
|
+
}
|
|
37540
37625
|
toggleBoldAxisTitle() {
|
|
37541
37626
|
const axesDesign = this.props.definition.axesDesign ?? {};
|
|
37542
37627
|
const title = axesDesign[this.state.currentAxis]?.title ?? {};
|
|
@@ -37656,8 +37741,12 @@ class GeneralDesignEditor extends owl.Component {
|
|
|
37656
37741
|
figureId: String,
|
|
37657
37742
|
definition: Object,
|
|
37658
37743
|
updateChart: Function,
|
|
37744
|
+
defaultChartTitleFontSize: { type: Number, optional: true },
|
|
37659
37745
|
slots: { type: Object, optional: true },
|
|
37660
37746
|
};
|
|
37747
|
+
static defaultProps = {
|
|
37748
|
+
defaultChartTitleFontSize: CHART_TITLE_FONT_SIZE,
|
|
37749
|
+
};
|
|
37661
37750
|
state;
|
|
37662
37751
|
setup() {
|
|
37663
37752
|
this.state = owl.useState({
|
|
@@ -37683,6 +37772,7 @@ class GeneralDesignEditor extends owl.Component {
|
|
|
37683
37772
|
get titleStyle() {
|
|
37684
37773
|
return {
|
|
37685
37774
|
align: "left",
|
|
37775
|
+
fontSize: this.props.defaultChartTitleFontSize,
|
|
37686
37776
|
...this.title,
|
|
37687
37777
|
};
|
|
37688
37778
|
}
|
|
@@ -37691,6 +37781,10 @@ class GeneralDesignEditor extends owl.Component {
|
|
|
37691
37781
|
this.props.updateChart(this.props.figureId, { title });
|
|
37692
37782
|
this.state.activeTool = "";
|
|
37693
37783
|
}
|
|
37784
|
+
updateChartTitleFontSize(fontSize) {
|
|
37785
|
+
const title = { ...this.title, fontSize };
|
|
37786
|
+
this.props.updateChart(this.props.figureId, { title });
|
|
37787
|
+
}
|
|
37694
37788
|
toggleBoldChartTitle() {
|
|
37695
37789
|
let title = this.title;
|
|
37696
37790
|
title = { ...title, bold: !title.bold };
|
|
@@ -37898,7 +37992,7 @@ class SeriesWithAxisDesignEditor extends owl.Component {
|
|
|
37898
37992
|
case "polynomial":
|
|
37899
37993
|
config = {
|
|
37900
37994
|
type: "polynomial",
|
|
37901
|
-
order: type === "linear" ? 1 :
|
|
37995
|
+
order: type === "linear" ? 1 : this.getMaxPolynomialDegree(index),
|
|
37902
37996
|
};
|
|
37903
37997
|
break;
|
|
37904
37998
|
case "exponential":
|
|
@@ -38358,6 +38452,9 @@ class ScorecardChartDesignPanel extends owl.Component {
|
|
|
38358
38452
|
get humanizeNumbersLabel() {
|
|
38359
38453
|
return _t("Humanize numbers");
|
|
38360
38454
|
}
|
|
38455
|
+
get defaultScorecardTitleFontSize() {
|
|
38456
|
+
return SCORECARD_CHART_TITLE_FONT_SIZE;
|
|
38457
|
+
}
|
|
38361
38458
|
updateHumanizeNumbers(humanize) {
|
|
38362
38459
|
this.props.updateChart(this.props.figureId, { humanize });
|
|
38363
38460
|
}
|
|
@@ -39821,6 +39918,15 @@ class StandaloneComposerStore extends AbstractComposerStore {
|
|
|
39821
39918
|
confirmEdition(content) {
|
|
39822
39919
|
this.args().onConfirm(content);
|
|
39823
39920
|
}
|
|
39921
|
+
getTokenColor(token) {
|
|
39922
|
+
if (token.type === "SYMBOL") {
|
|
39923
|
+
const matchedColor = this.args().getContextualColoredSymbolToken?.(token);
|
|
39924
|
+
if (matchedColor) {
|
|
39925
|
+
return matchedColor;
|
|
39926
|
+
}
|
|
39927
|
+
}
|
|
39928
|
+
return super.getTokenColor(token);
|
|
39929
|
+
}
|
|
39824
39930
|
}
|
|
39825
39931
|
|
|
39826
39932
|
css /* scss */ `
|
|
@@ -39858,6 +39964,7 @@ class StandaloneComposer extends owl.Component {
|
|
|
39858
39964
|
placeholder: { type: String, optional: true },
|
|
39859
39965
|
class: { type: String, optional: true },
|
|
39860
39966
|
invalid: { type: Boolean, optional: true },
|
|
39967
|
+
getContextualColoredSymbolToken: { type: Function, optional: true },
|
|
39861
39968
|
};
|
|
39862
39969
|
static components = { Composer };
|
|
39863
39970
|
static defaultProps = {
|
|
@@ -39874,6 +39981,7 @@ class StandaloneComposer extends owl.Component {
|
|
|
39874
39981
|
content: this.props.composerContent,
|
|
39875
39982
|
contextualAutocomplete: this.props.contextualAutocomplete,
|
|
39876
39983
|
defaultRangeSheetId: this.props.defaultRangeSheetId,
|
|
39984
|
+
getContextualColoredSymbolToken: this.props.getContextualColoredSymbolToken,
|
|
39877
39985
|
}));
|
|
39878
39986
|
this.standaloneComposerStore = standaloneComposerStore;
|
|
39879
39987
|
this.composerInterface = {
|
|
@@ -43434,7 +43542,7 @@ function createMeasureAutoComplete(pivot, forComputedMeasure) {
|
|
|
43434
43542
|
return {
|
|
43435
43543
|
text: text,
|
|
43436
43544
|
description: measure.displayName,
|
|
43437
|
-
htmlContent: [{ value: text, color:
|
|
43545
|
+
htmlContent: [{ value: text, color: PIVOT_TOKEN_COLOR }],
|
|
43438
43546
|
fuzzySearchKey: measure.displayName + text + measure.fieldName,
|
|
43439
43547
|
};
|
|
43440
43548
|
});
|
|
@@ -43443,7 +43551,7 @@ function createMeasureAutoComplete(pivot, forComputedMeasure) {
|
|
|
43443
43551
|
return {
|
|
43444
43552
|
text: text,
|
|
43445
43553
|
description: dimension.displayName,
|
|
43446
|
-
htmlContent: [{ value: text, color:
|
|
43554
|
+
htmlContent: [{ value: text, color: PIVOT_TOKEN_COLOR }],
|
|
43447
43555
|
fuzzySearchKey: dimension.displayName + text + dimension.fieldName,
|
|
43448
43556
|
};
|
|
43449
43557
|
});
|
|
@@ -43523,6 +43631,18 @@ class PivotMeasureEditor extends owl.Component {
|
|
|
43523
43631
|
measure: this.props.measure,
|
|
43524
43632
|
});
|
|
43525
43633
|
}
|
|
43634
|
+
getColoredSymbolToken(token) {
|
|
43635
|
+
if (token.type !== "SYMBOL") {
|
|
43636
|
+
return undefined;
|
|
43637
|
+
}
|
|
43638
|
+
const tokenValue = unquote(token.value, "'");
|
|
43639
|
+
if (this.props.definition.columns.some((col) => col.nameWithGranularity === tokenValue) ||
|
|
43640
|
+
this.props.definition.rows.some((row) => row.nameWithGranularity === tokenValue) ||
|
|
43641
|
+
this.props.definition.measures.some((measure) => measure.id === tokenValue && measure.id !== this.props.measure.id)) {
|
|
43642
|
+
return PIVOT_TOKEN_COLOR;
|
|
43643
|
+
}
|
|
43644
|
+
return undefined;
|
|
43645
|
+
}
|
|
43526
43646
|
}
|
|
43527
43647
|
|
|
43528
43648
|
css /* scss */ `
|
|
@@ -51897,7 +52017,7 @@ class CellPlugin extends CorePlugin {
|
|
|
51897
52017
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
51898
52018
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
51899
52019
|
const cell = this.getters.getCell({ sheetId, col, row });
|
|
51900
|
-
if (cell) {
|
|
52020
|
+
if (cell?.isFormula || cell?.content) {
|
|
51901
52021
|
this.dispatch("UPDATE_CELL", {
|
|
51902
52022
|
sheetId: sheetId,
|
|
51903
52023
|
content: "",
|
|
@@ -51933,7 +52053,6 @@ class CellPlugin extends CorePlugin {
|
|
|
51933
52053
|
for (let zone of recomputeZones(zones)) {
|
|
51934
52054
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
51935
52055
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
51936
|
-
// commandHelpers.updateCell(sheetId, col, row, { style: undefined});
|
|
51937
52056
|
this.dispatch("UPDATE_CELL", {
|
|
51938
52057
|
sheetId,
|
|
51939
52058
|
col,
|
|
@@ -52904,8 +53023,6 @@ class ConditionalFormatPlugin extends CorePlugin {
|
|
|
52904
53023
|
case "IconSetRule": {
|
|
52905
53024
|
return this.checkValidations(rule, this.chainValidations(this.checkInflectionPoints(this.checkNaN), this.checkLowerBiggerThanUpper), this.chainValidations(this.checkInflectionPoints(this.checkFormulaCompilation)));
|
|
52906
53025
|
}
|
|
52907
|
-
case "DataBarRule":
|
|
52908
|
-
return this.checkDataBarRangeValues(rule, cmd.ranges, cmd.sheetId);
|
|
52909
53026
|
}
|
|
52910
53027
|
return "Success" /* CommandResult.Success */;
|
|
52911
53028
|
}
|
|
@@ -53036,18 +53153,6 @@ class ConditionalFormatPlugin extends CorePlugin {
|
|
|
53036
53153
|
}
|
|
53037
53154
|
return "Success" /* CommandResult.Success */;
|
|
53038
53155
|
}
|
|
53039
|
-
checkDataBarRangeValues(rule, ranges, sheetId) {
|
|
53040
|
-
if (rule.rangeValues) {
|
|
53041
|
-
const { numberOfCols, numberOfRows } = zoneToDimension(this.getters.getRangeFromSheetXC(sheetId, rule.rangeValues).zone);
|
|
53042
|
-
for (const range of ranges) {
|
|
53043
|
-
const dimensions = zoneToDimension(this.getters.getRangeFromRangeData(range).zone);
|
|
53044
|
-
if (numberOfCols !== dimensions.numberOfCols || numberOfRows !== dimensions.numberOfRows) {
|
|
53045
|
-
return "DataBarRangeValuesMismatch" /* CommandResult.DataBarRangeValuesMismatch */;
|
|
53046
|
-
}
|
|
53047
|
-
}
|
|
53048
|
-
}
|
|
53049
|
-
return "Success" /* CommandResult.Success */;
|
|
53050
|
-
}
|
|
53051
53156
|
removeConditionalFormatting(id, sheet) {
|
|
53052
53157
|
const cfIndex = this.cfRules[sheet].findIndex((s) => s.id === id);
|
|
53053
53158
|
if (cfIndex !== -1) {
|
|
@@ -55366,7 +55471,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
55366
55471
|
if (orderedSheetIds.find((id) => sheets[id]?.name.toLowerCase() === name && id !== cmd.sheetId)) {
|
|
55367
55472
|
return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
|
|
55368
55473
|
}
|
|
55369
|
-
if (
|
|
55474
|
+
if (FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX.test(name)) {
|
|
55370
55475
|
return "ForbiddenCharactersInSheetName" /* CommandResult.ForbiddenCharactersInSheetName */;
|
|
55371
55476
|
}
|
|
55372
55477
|
return "Success" /* CommandResult.Success */;
|
|
@@ -59452,8 +59557,12 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
|
|
|
59452
59557
|
const zoneOfValues = rangeValues.zone;
|
|
59453
59558
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
59454
59559
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
59455
|
-
const
|
|
59456
|
-
|
|
59560
|
+
const targetCol = col - zone.left + zoneOfValues.left;
|
|
59561
|
+
const targetRow = row - zone.top + zoneOfValues.top;
|
|
59562
|
+
const cell = this.getters.getEvaluatedCell({ sheetId, col: targetCol, row: targetRow });
|
|
59563
|
+
if (!isInside(targetCol, targetRow, zoneOfValues) ||
|
|
59564
|
+
cell.type !== CellValueType.number ||
|
|
59565
|
+
cell.value <= 0) {
|
|
59457
59566
|
// values negatives or 0 are ignored
|
|
59458
59567
|
continue;
|
|
59459
59568
|
}
|
|
@@ -59466,11 +59575,6 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
|
|
|
59466
59575
|
}
|
|
59467
59576
|
}
|
|
59468
59577
|
}
|
|
59469
|
-
getEvaluatedCellInZone(sheetId, zone, col, row, targetZone) {
|
|
59470
|
-
const targetCol = col - zone.left + targetZone.left;
|
|
59471
|
-
const targetRow = row - zone.top + targetZone.top;
|
|
59472
|
-
return this.getters.getEvaluatedCell({ sheetId, col: targetCol, row: targetRow });
|
|
59473
|
-
}
|
|
59474
59578
|
/** Compute the color scale for the given range and CF rule, and apply in in the given computedStyle object */
|
|
59475
59579
|
applyColorScale(sheetId, range, rule, computedStyle) {
|
|
59476
59580
|
const minValue = this.parsePoint(sheetId, range, rule.minimum, "min");
|
|
@@ -60775,11 +60879,13 @@ class PivotUIPlugin extends UIPlugin {
|
|
|
60775
60879
|
return EMPTY_PIVOT_CELL;
|
|
60776
60880
|
}
|
|
60777
60881
|
if (functionName === "PIVOT") {
|
|
60778
|
-
const includeTotal = args[2]
|
|
60779
|
-
const
|
|
60882
|
+
const includeTotal = toScalar(args[2]);
|
|
60883
|
+
const shouldIncludeTotal = includeTotal === undefined ? true : toBoolean(includeTotal);
|
|
60884
|
+
const includeColumnHeaders = toScalar(args[3]);
|
|
60885
|
+
const shouldIncludeColumnHeaders = includeColumnHeaders === undefined ? true : toBoolean(includeColumnHeaders);
|
|
60780
60886
|
const pivotCells = pivot
|
|
60781
60887
|
.getTableStructure()
|
|
60782
|
-
.getPivotCells(
|
|
60888
|
+
.getPivotCells(shouldIncludeTotal, shouldIncludeColumnHeaders);
|
|
60783
60889
|
const pivotCol = position.col - mainPosition.col;
|
|
60784
60890
|
const pivotRow = position.row - mainPosition.row;
|
|
60785
60891
|
return pivotCells[pivotCol][pivotRow];
|
|
@@ -62933,7 +63039,7 @@ class InsertPivotPlugin extends UIPlugin {
|
|
|
62933
63039
|
getPivotDuplicateSheetName(pivotName) {
|
|
62934
63040
|
let i = 1;
|
|
62935
63041
|
const names = this.getters.getSheetIds().map((id) => this.getters.getSheetName(id));
|
|
62936
|
-
const sanitizedName = pivotName
|
|
63042
|
+
const sanitizedName = sanitizeSheetName(pivotName);
|
|
62937
63043
|
let name = sanitizedName;
|
|
62938
63044
|
while (names.includes(name)) {
|
|
62939
63045
|
name = `${sanitizedName} (${i})`;
|
|
@@ -63048,9 +63154,9 @@ class SortPlugin extends UIPlugin {
|
|
|
63048
63154
|
switch (cmd.type) {
|
|
63049
63155
|
case "SORT_CELLS":
|
|
63050
63156
|
if (!isInside(cmd.col, cmd.row, cmd.zone)) {
|
|
63051
|
-
|
|
63157
|
+
return "InvalidSortAnchor" /* CommandResult.InvalidSortAnchor */;
|
|
63052
63158
|
}
|
|
63053
|
-
return this.checkValidations(cmd, this.checkMerge, this.checkMergeSizes);
|
|
63159
|
+
return this.checkValidations(cmd, this.checkMerge, this.checkMergeSizes, this.checkArrayFormulaInSortZone);
|
|
63054
63160
|
}
|
|
63055
63161
|
return "Success" /* CommandResult.Success */;
|
|
63056
63162
|
}
|
|
@@ -63091,6 +63197,10 @@ class SortPlugin extends UIPlugin {
|
|
|
63091
63197
|
}
|
|
63092
63198
|
return "Success" /* CommandResult.Success */;
|
|
63093
63199
|
}
|
|
63200
|
+
checkArrayFormulaInSortZone({ sheetId, zone }) {
|
|
63201
|
+
const arrayFormulaInZone = positions(zone).some(({ col, row }) => this.getters.getArrayFormulaSpreadingOn({ sheetId, col, row }));
|
|
63202
|
+
return arrayFormulaInZone ? "SortZoneWithArrayFormulas" /* CommandResult.SortZoneWithArrayFormulas */ : "Success" /* CommandResult.Success */;
|
|
63203
|
+
}
|
|
63094
63204
|
/**
|
|
63095
63205
|
* This function evaluates if the top row of a provided zone can be considered as a `header`
|
|
63096
63206
|
* by checking the following criteria:
|
|
@@ -67005,7 +67115,7 @@ function interactiveRenameSheet(env, sheetId, name, errorCallback) {
|
|
|
67005
67115
|
env.raiseError(_t("A sheet with the name %s already exists. Please select another name.", name), errorCallback);
|
|
67006
67116
|
}
|
|
67007
67117
|
else if (result.reasons.includes("ForbiddenCharactersInSheetName" /* CommandResult.ForbiddenCharactersInSheetName */)) {
|
|
67008
|
-
env.raiseError(_t("Some used characters are not allowed in a sheet name (Forbidden characters are %s).",
|
|
67118
|
+
env.raiseError(_t("Some used characters are not allowed in a sheet name (Forbidden characters are %s).", FORBIDDEN_SHEETNAME_CHARS.join(" ")), errorCallback);
|
|
67009
67119
|
}
|
|
67010
67120
|
}
|
|
67011
67121
|
|
|
@@ -68235,7 +68345,7 @@ class ActionButton extends owl.Component {
|
|
|
68235
68345
|
setup() {
|
|
68236
68346
|
owl.onWillUpdateProps((nextProps) => {
|
|
68237
68347
|
if (nextProps.action !== this.props.action) {
|
|
68238
|
-
this.actionButton = createAction(
|
|
68348
|
+
this.actionButton = createAction(nextProps.action);
|
|
68239
68349
|
}
|
|
68240
68350
|
});
|
|
68241
68351
|
}
|
|
@@ -68571,88 +68681,6 @@ class TopBarComposer extends owl.Component {
|
|
|
68571
68681
|
}
|
|
68572
68682
|
}
|
|
68573
68683
|
|
|
68574
|
-
css /* scss */ `
|
|
68575
|
-
.o-font-size-editor {
|
|
68576
|
-
height: calc(100% - 4px);
|
|
68577
|
-
input.o-font-size {
|
|
68578
|
-
outline-color: ${SELECTION_BORDER_COLOR};
|
|
68579
|
-
height: 20px;
|
|
68580
|
-
width: 23px;
|
|
68581
|
-
}
|
|
68582
|
-
}
|
|
68583
|
-
.o-text-options > div {
|
|
68584
|
-
cursor: pointer;
|
|
68585
|
-
line-height: 26px;
|
|
68586
|
-
padding: 3px 12px;
|
|
68587
|
-
&:hover {
|
|
68588
|
-
background-color: rgba(0, 0, 0, 0.08);
|
|
68589
|
-
}
|
|
68590
|
-
}
|
|
68591
|
-
`;
|
|
68592
|
-
class FontSizeEditor extends owl.Component {
|
|
68593
|
-
static template = "o-spreadsheet-FontSizeEditor";
|
|
68594
|
-
static props = {
|
|
68595
|
-
onToggle: Function,
|
|
68596
|
-
dropdownStyle: String,
|
|
68597
|
-
class: String,
|
|
68598
|
-
};
|
|
68599
|
-
static components = {};
|
|
68600
|
-
fontSizes = FONT_SIZES;
|
|
68601
|
-
dropdown = owl.useState({ isOpen: false });
|
|
68602
|
-
inputRef = owl.useRef("inputFontSize");
|
|
68603
|
-
rootEditorRef = owl.useRef("FontSizeEditor");
|
|
68604
|
-
setup() {
|
|
68605
|
-
owl.useExternalListener(window, "click", this.onExternalClick, { capture: true });
|
|
68606
|
-
}
|
|
68607
|
-
onExternalClick(ev) {
|
|
68608
|
-
if (!isChildEvent(this.rootEditorRef.el, ev)) {
|
|
68609
|
-
this.closeFontList();
|
|
68610
|
-
}
|
|
68611
|
-
}
|
|
68612
|
-
get currentFontSize() {
|
|
68613
|
-
return this.env.model.getters.getCurrentStyle().fontSize || DEFAULT_FONT_SIZE;
|
|
68614
|
-
}
|
|
68615
|
-
toggleFontList() {
|
|
68616
|
-
const isOpen = this.dropdown.isOpen;
|
|
68617
|
-
if (!isOpen) {
|
|
68618
|
-
this.props.onToggle();
|
|
68619
|
-
this.inputRef.el.focus();
|
|
68620
|
-
}
|
|
68621
|
-
else {
|
|
68622
|
-
this.closeFontList();
|
|
68623
|
-
}
|
|
68624
|
-
}
|
|
68625
|
-
closeFontList() {
|
|
68626
|
-
this.dropdown.isOpen = false;
|
|
68627
|
-
}
|
|
68628
|
-
setSize(fontSizeStr) {
|
|
68629
|
-
const fontSize = clip(Math.floor(parseFloat(fontSizeStr)), 1, 400);
|
|
68630
|
-
setStyle(this.env, { fontSize });
|
|
68631
|
-
this.closeFontList();
|
|
68632
|
-
}
|
|
68633
|
-
setSizeFromInput(ev) {
|
|
68634
|
-
this.setSize(ev.target.value);
|
|
68635
|
-
}
|
|
68636
|
-
setSizeFromList(fontSizeStr) {
|
|
68637
|
-
this.setSize(fontSizeStr);
|
|
68638
|
-
}
|
|
68639
|
-
onInputFocused(ev) {
|
|
68640
|
-
this.dropdown.isOpen = true;
|
|
68641
|
-
ev.target.select();
|
|
68642
|
-
}
|
|
68643
|
-
onInputKeydown(ev) {
|
|
68644
|
-
if (ev.key === "Enter" || ev.key === "Escape") {
|
|
68645
|
-
this.closeFontList();
|
|
68646
|
-
const target = ev.target;
|
|
68647
|
-
// In the case of a ESCAPE key, we get the previous font size back
|
|
68648
|
-
if (ev.key === "Escape") {
|
|
68649
|
-
target.value = `${this.currentFontSize}`;
|
|
68650
|
-
}
|
|
68651
|
-
this.props.onToggle();
|
|
68652
|
-
}
|
|
68653
|
-
}
|
|
68654
|
-
}
|
|
68655
|
-
|
|
68656
68684
|
class TableDropdownButton extends owl.Component {
|
|
68657
68685
|
static template = "o-spreadsheet-TableDropdownButton";
|
|
68658
68686
|
static components = { TableStylesPopover, ActionButton };
|
|
@@ -68821,9 +68849,6 @@ class TopBar extends owl.Component {
|
|
|
68821
68849
|
onClick: Function,
|
|
68822
68850
|
dropdownMaxHeight: Number,
|
|
68823
68851
|
};
|
|
68824
|
-
get dropdownStyle() {
|
|
68825
|
-
return `max-height:${this.props.dropdownMaxHeight}px`;
|
|
68826
|
-
}
|
|
68827
68852
|
static components = {
|
|
68828
68853
|
ColorPickerWidget,
|
|
68829
68854
|
ColorPicker,
|
|
@@ -68861,6 +68886,9 @@ class TopBar extends owl.Component {
|
|
|
68861
68886
|
.getAllOrdered()
|
|
68862
68887
|
.filter((item) => !item.isVisible || item.isVisible(this.env));
|
|
68863
68888
|
}
|
|
68889
|
+
get currentFontSize() {
|
|
68890
|
+
return this.env.model.getters.getCurrentStyle().fontSize || DEFAULT_FONT_SIZE;
|
|
68891
|
+
}
|
|
68864
68892
|
onExternalClick(ev) {
|
|
68865
68893
|
// TODO : manage click events better. We need this piece of code
|
|
68866
68894
|
// otherwise the event opening the menu would close it on the same frame.
|
|
@@ -68939,6 +68967,9 @@ class TopBar extends owl.Component {
|
|
|
68939
68967
|
setStyle(this.env, { [target]: color });
|
|
68940
68968
|
this.onClick();
|
|
68941
68969
|
}
|
|
68970
|
+
setFontSize(fontSize) {
|
|
68971
|
+
setStyle(this.env, { fontSize });
|
|
68972
|
+
}
|
|
68942
68973
|
}
|
|
68943
68974
|
|
|
68944
68975
|
function instantiateClipboard() {
|
|
@@ -70939,12 +70970,11 @@ function createChart(chart, chartSheetIndex, data) {
|
|
|
70939
70970
|
// <manualLayout/> to manually position the chart in the figure container
|
|
70940
70971
|
let title = escapeXml ``;
|
|
70941
70972
|
if (chart.data.title?.text) {
|
|
70942
|
-
const
|
|
70943
|
-
|
|
70944
|
-
: chart.data.fontColor;
|
|
70973
|
+
const titleColor = toXlsxHexColor(chartMutedFontColor(chart.data.backgroundColor));
|
|
70974
|
+
const fontSize = chart.data.title.fontSize ?? CHART_TITLE_FONT_SIZE;
|
|
70945
70975
|
title = escapeXml /*xml*/ `
|
|
70946
70976
|
<c:title>
|
|
70947
|
-
${insertText(chart.data.title.text,
|
|
70977
|
+
${insertText(chart.data.title.text, titleColor, fontSize, chart.data.title)}
|
|
70948
70978
|
<c:overlay val="0" />
|
|
70949
70979
|
</c:title>
|
|
70950
70980
|
`;
|
|
@@ -71034,7 +71064,7 @@ function lineAttributes(params) {
|
|
|
71034
71064
|
</a:ln>
|
|
71035
71065
|
`;
|
|
71036
71066
|
}
|
|
71037
|
-
function insertText(text, fontColor = "000000", fontsize =
|
|
71067
|
+
function insertText(text, fontColor = "000000", fontsize = CHART_TITLE_FONT_SIZE, style = {}) {
|
|
71038
71068
|
return escapeXml /*xml*/ `
|
|
71039
71069
|
<c:tx>
|
|
71040
71070
|
<c:rich>
|
|
@@ -71535,6 +71565,7 @@ function addAx(position, axisName, axId, crossAxId, title, defaultFontColor, del
|
|
|
71535
71565
|
// Each Axis present inside a graph needs to be identified by an unsigned integer in order to be referenced by its crossAxis.
|
|
71536
71566
|
// I.e. x-axis, will reference y-axis and vice-versa.
|
|
71537
71567
|
const color = title?.color ? toXlsxHexColor(title.color) : defaultFontColor;
|
|
71568
|
+
const fontSize = title?.fontSize ?? CHART_AXIS_TITLE_FONT_SIZE;
|
|
71538
71569
|
return escapeXml /*xml*/ `
|
|
71539
71570
|
<${axisName}>
|
|
71540
71571
|
<c:axId val="${axId}"/>
|
|
@@ -71550,7 +71581,7 @@ function addAx(position, axisName, axId, crossAxId, title, defaultFontColor, del
|
|
|
71550
71581
|
<c:minorTickMark val="none" />
|
|
71551
71582
|
<c:numFmt formatCode="General" sourceLinked="1" />
|
|
71552
71583
|
<c:title>
|
|
71553
|
-
${insertText(title?.text ?? "", color,
|
|
71584
|
+
${insertText(title?.text ?? "", color, fontSize, title)}
|
|
71554
71585
|
</c:title>
|
|
71555
71586
|
${insertTextProperties(10, defaultFontColor)}
|
|
71556
71587
|
</${axisName}>
|
|
@@ -73661,6 +73692,7 @@ const helpers = {
|
|
|
73661
73692
|
createPivotFormula,
|
|
73662
73693
|
areDomainArgsFieldsValid,
|
|
73663
73694
|
splitReference,
|
|
73695
|
+
sanitizeSheetName,
|
|
73664
73696
|
};
|
|
73665
73697
|
const links = {
|
|
73666
73698
|
isMarkdownLink,
|
|
@@ -73692,6 +73724,9 @@ const components = {
|
|
|
73692
73724
|
GaugeChartDesignPanel,
|
|
73693
73725
|
ScorecardChartConfigPanel,
|
|
73694
73726
|
ScorecardChartDesignPanel,
|
|
73727
|
+
RadarChartDesignPanel,
|
|
73728
|
+
WaterfallChartDesignPanel,
|
|
73729
|
+
ComboChartDesignPanel,
|
|
73695
73730
|
ChartTypePicker,
|
|
73696
73731
|
FigureComponent,
|
|
73697
73732
|
Menu,
|
|
@@ -73745,6 +73780,7 @@ const constants = {
|
|
|
73745
73780
|
DEFAULT_LOCALE,
|
|
73746
73781
|
HIGHLIGHT_COLOR,
|
|
73747
73782
|
PIVOT_TABLE_CONFIG,
|
|
73783
|
+
ChartTerms,
|
|
73748
73784
|
};
|
|
73749
73785
|
const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
|
|
73750
73786
|
|
|
@@ -73795,6 +73831,6 @@ exports.tokenColors = tokenColors;
|
|
|
73795
73831
|
exports.tokenize = tokenize;
|
|
73796
73832
|
|
|
73797
73833
|
|
|
73798
|
-
__info__.version = "18.1.0-alpha.
|
|
73799
|
-
__info__.date = "2024-
|
|
73800
|
-
__info__.hash = "
|
|
73834
|
+
__info__.version = "18.1.0-alpha.7";
|
|
73835
|
+
__info__.date = "2024-12-05T10:40:26.512Z";
|
|
73836
|
+
__info__.hash = "7b1c39b";
|