@odoo/o-spreadsheet 18.5.0-alpha.3 → 18.5.0-alpha.5
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 +291 -120
- package/dist/o-spreadsheet.d.ts +313 -159
- package/dist/o-spreadsheet.esm.js +291 -120
- package/dist/o-spreadsheet.iife.js +291 -120
- package/dist/o-spreadsheet.iife.min.js +419 -450
- package/dist/o_spreadsheet.xml +18 -14
- 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.5.0-alpha.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.5.0-alpha.5
|
|
6
|
+
* @date 2025-08-04T06:53:29.412Z
|
|
7
|
+
* @hash 71c9a36
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, useExternalListener, onWillUpdateProps, onWillStart, onWillPatch, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -1056,16 +1056,21 @@ const colors = [
|
|
|
1056
1056
|
"#001f3f",
|
|
1057
1057
|
];
|
|
1058
1058
|
/*
|
|
1059
|
-
* transform a color number (R * 256^2 + G * 256 + B) into classic
|
|
1059
|
+
* transform a color number (R * 256^2 + G * 256 + B) into classic hex (+alpha) value
|
|
1060
1060
|
* */
|
|
1061
|
-
function
|
|
1062
|
-
|
|
1061
|
+
function colorNumberToHex(color, alpha = 1) {
|
|
1062
|
+
const alphaHex = alpha !== 1
|
|
1063
|
+
? Math.round(alpha * 255)
|
|
1064
|
+
.toString(16)
|
|
1065
|
+
.padStart(2, "0")
|
|
1066
|
+
: "";
|
|
1067
|
+
return toHex(color.toString(16).padStart(6, "0")) + alphaHex;
|
|
1063
1068
|
}
|
|
1064
1069
|
function colorToNumber(color) {
|
|
1065
1070
|
if (typeof color === "number") {
|
|
1066
1071
|
return color;
|
|
1067
1072
|
}
|
|
1068
|
-
return Number.parseInt(toHex(color).slice(1), 16);
|
|
1073
|
+
return Number.parseInt(toHex(color).slice(1, 7), 16);
|
|
1069
1074
|
}
|
|
1070
1075
|
/**
|
|
1071
1076
|
* Converts any CSS color value to a standardized hex6 value.
|
|
@@ -1324,6 +1329,12 @@ function hslaToHex(hsla) {
|
|
|
1324
1329
|
function hexToHSLA(hex) {
|
|
1325
1330
|
return rgbaToHSLA(colorToRGBA(hex));
|
|
1326
1331
|
}
|
|
1332
|
+
function colorOrNumberToRGBA(color) {
|
|
1333
|
+
if (typeof color === "number") {
|
|
1334
|
+
return colorToRGBA(colorNumberToHex(color));
|
|
1335
|
+
}
|
|
1336
|
+
return colorToRGBA(color);
|
|
1337
|
+
}
|
|
1327
1338
|
/**
|
|
1328
1339
|
* Will compare two color strings
|
|
1329
1340
|
* A tolerance can be provided to account for small differences that could
|
|
@@ -1605,6 +1616,8 @@ function getColorScale(colorScalePoints) {
|
|
|
1605
1616
|
const sortedColorScalePoints = [...colorScalePoints.sort((a, b) => a.value - b.value)];
|
|
1606
1617
|
const thresholds = [];
|
|
1607
1618
|
for (let i = 1; i < sortedColorScalePoints.length; i++) {
|
|
1619
|
+
const minColorAlpha = colorOrNumberToRGBA(sortedColorScalePoints[i - 1].color).a;
|
|
1620
|
+
const maxColorAlpha = colorOrNumberToRGBA(sortedColorScalePoints[i].color).a;
|
|
1608
1621
|
const minColor = colorToNumber(sortedColorScalePoints[i - 1].color);
|
|
1609
1622
|
const maxColor = colorToNumber(sortedColorScalePoints[i].color);
|
|
1610
1623
|
thresholds.push({
|
|
@@ -1612,19 +1625,21 @@ function getColorScale(colorScalePoints) {
|
|
|
1612
1625
|
max: sortedColorScalePoints[i].value,
|
|
1613
1626
|
minColor,
|
|
1614
1627
|
maxColor,
|
|
1628
|
+
minColorAlpha: minColorAlpha,
|
|
1629
|
+
maxColorAlpha: maxColorAlpha,
|
|
1615
1630
|
colorDiff: computeColorDiffUnits(sortedColorScalePoints[i - 1].value, sortedColorScalePoints[i].value, minColor, maxColor),
|
|
1616
1631
|
});
|
|
1617
1632
|
}
|
|
1618
1633
|
return (value) => {
|
|
1619
1634
|
if (value < thresholds[0].min) {
|
|
1620
|
-
return
|
|
1635
|
+
return colorNumberToHex(thresholds[0].minColor, thresholds[0].minColorAlpha);
|
|
1621
1636
|
}
|
|
1622
1637
|
for (const threshold of thresholds) {
|
|
1623
1638
|
if (value >= threshold.min && value <= threshold.max) {
|
|
1624
|
-
return
|
|
1639
|
+
return colorNumberToHex(colorCell(value, threshold.min, threshold.minColor, threshold.colorDiff), threshold.maxColorAlpha);
|
|
1625
1640
|
}
|
|
1626
1641
|
}
|
|
1627
|
-
return
|
|
1642
|
+
return colorNumberToHex(thresholds[thresholds.length - 1].maxColor, thresholds[thresholds.length - 1].maxColorAlpha);
|
|
1628
1643
|
};
|
|
1629
1644
|
}
|
|
1630
1645
|
function computeColorDiffUnits(minValue, maxValue, minColor, maxColor) {
|
|
@@ -8638,12 +8653,12 @@ const AGGREGATOR_NAMES = {
|
|
|
8638
8653
|
avg: _t("Average"),
|
|
8639
8654
|
sum: _t("Sum"),
|
|
8640
8655
|
};
|
|
8641
|
-
const
|
|
8656
|
+
const DEFAULT_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
|
|
8642
8657
|
const AGGREGATORS_BY_FIELD_TYPE = {
|
|
8643
|
-
integer:
|
|
8644
|
-
char:
|
|
8658
|
+
integer: DEFAULT_AGGREGATORS,
|
|
8659
|
+
char: DEFAULT_AGGREGATORS,
|
|
8660
|
+
datetime: DEFAULT_AGGREGATORS,
|
|
8645
8661
|
boolean: ["count_distinct", "count", "bool_and", "bool_or"],
|
|
8646
|
-
datetime: ["max", "min", "count_distinct", "count"],
|
|
8647
8662
|
};
|
|
8648
8663
|
const AGGREGATORS = {};
|
|
8649
8664
|
for (const type in AGGREGATORS_BY_FIELD_TYPE) {
|
|
@@ -20476,6 +20491,54 @@ const PROPER = {
|
|
|
20476
20491
|
},
|
|
20477
20492
|
isExported: true,
|
|
20478
20493
|
};
|
|
20494
|
+
const REGEXEXTRACT_DEFAULT_MODE = 0;
|
|
20495
|
+
const REGEXEXTRACT_DEFAULT_CASE_SENSITIVITY = 0;
|
|
20496
|
+
// -----------------------------------------------------------------------------
|
|
20497
|
+
// REGEXEXTRACT
|
|
20498
|
+
// -----------------------------------------------------------------------------
|
|
20499
|
+
const REGEXEXTRACT = {
|
|
20500
|
+
description: _t("Extract text from a string based on the supplied regular expression."),
|
|
20501
|
+
args: [
|
|
20502
|
+
arg("text (string)", _t("The string on which you want to extract text.")),
|
|
20503
|
+
arg("pattern (string)", _t("The regular expression pattern to match against the text.")),
|
|
20504
|
+
arg(`return_mode (number, default=${REGEXEXTRACT_DEFAULT_MODE})`, _t("0 = first match, 1 = all matches as an array, 2 = capturing groups from the first match as an array.")),
|
|
20505
|
+
arg(`case_sensitivity (number, default=${REGEXEXTRACT_DEFAULT_CASE_SENSITIVITY})`, _t("0 = case-sensitive, 1 = case-insensitive.")),
|
|
20506
|
+
],
|
|
20507
|
+
compute: function (text, pattern, return_mode = { value: REGEXEXTRACT_DEFAULT_MODE }, newText = { value: REGEXEXTRACT_DEFAULT_CASE_SENSITIVITY }) {
|
|
20508
|
+
const _text = toString(text);
|
|
20509
|
+
const _pattern = toString(pattern);
|
|
20510
|
+
const _returnMode = toNumber(return_mode, this.locale);
|
|
20511
|
+
const _caseSensitivity = toNumber(newText, this.locale);
|
|
20512
|
+
if (_text === "" || _pattern === "") {
|
|
20513
|
+
return { value: "" };
|
|
20514
|
+
}
|
|
20515
|
+
if (_returnMode < 0 || _returnMode > 2) {
|
|
20516
|
+
return new EvaluationError(_t("The return_mode (%s) must be 0, 1 or 2.", _returnMode));
|
|
20517
|
+
}
|
|
20518
|
+
if (_caseSensitivity !== 0 && _caseSensitivity !== 1) {
|
|
20519
|
+
return new EvaluationError(_t("The case_sensitivity (%s) must be 0 or 1.", _caseSensitivity));
|
|
20520
|
+
}
|
|
20521
|
+
const flags = _caseSensitivity === 1 ? "gi" : "g";
|
|
20522
|
+
const regex = new RegExp(_pattern, flags);
|
|
20523
|
+
const matches = [..._text.matchAll(regex)];
|
|
20524
|
+
if (matches.length === 0) {
|
|
20525
|
+
return { value: CellErrorType.NotAvailable, message: _t("No matches found.") };
|
|
20526
|
+
}
|
|
20527
|
+
if (_returnMode === 0) {
|
|
20528
|
+
return matches[0][0];
|
|
20529
|
+
}
|
|
20530
|
+
else if (_returnMode === 1) {
|
|
20531
|
+
return matches.map((match) => [match[0]]);
|
|
20532
|
+
}
|
|
20533
|
+
else {
|
|
20534
|
+
if (matches[0].length < 2) {
|
|
20535
|
+
return new EvaluationError(_t("No capturing groups found."));
|
|
20536
|
+
}
|
|
20537
|
+
return matches[0].slice(1).map((s) => [s]);
|
|
20538
|
+
}
|
|
20539
|
+
},
|
|
20540
|
+
isExported: true,
|
|
20541
|
+
};
|
|
20479
20542
|
// -----------------------------------------------------------------------------
|
|
20480
20543
|
// REPLACE
|
|
20481
20544
|
// -----------------------------------------------------------------------------
|
|
@@ -20752,6 +20815,105 @@ const VALUE = {
|
|
|
20752
20815
|
},
|
|
20753
20816
|
isExported: true,
|
|
20754
20817
|
};
|
|
20818
|
+
// -----------------------------------------------------------------------------
|
|
20819
|
+
// TEXTAFTER
|
|
20820
|
+
// -----------------------------------------------------------------------------
|
|
20821
|
+
const TEXT_FN_DEFAULT_INSTANCE = 1;
|
|
20822
|
+
const TEXT_FN_DEFAULT_MATCH_MODE = 0;
|
|
20823
|
+
const TEXT_FN_DEFAULT_MATCH_END = 0;
|
|
20824
|
+
const TEXTAFTER = {
|
|
20825
|
+
description: _t("Returns text that occurs after a given substring or delimiter."),
|
|
20826
|
+
args: [
|
|
20827
|
+
arg("text (string)", _t("The source text.")),
|
|
20828
|
+
arg("delimiter (string)", _t("The substring after which text will be returned.")),
|
|
20829
|
+
arg(`instance_num (number, default=${TEXT_FN_DEFAULT_INSTANCE})`, _t("The desired instance of the delimiter after which we extract the text. A negative number searches from the end.")),
|
|
20830
|
+
arg(`match_mode (number, default=${TEXT_FN_DEFAULT_MATCH_MODE})`, _t("0 = case-sensitive, 1 = case-insensitive.")),
|
|
20831
|
+
arg(`match_end (number, default=${TEXT_FN_DEFAULT_MATCH_END}))`, _t("Whether to treat the end of text as a delimiter.")),
|
|
20832
|
+
arg(`if_not_found (string, default="${CellErrorType.NotAvailable}")`, _t("Value to return if the delimiter is not found.")),
|
|
20833
|
+
],
|
|
20834
|
+
compute: function (text, delimiter, matchIndex = { value: TEXT_FN_DEFAULT_INSTANCE }, matchMode = { value: TEXT_FN_DEFAULT_MATCH_MODE }, matchEnd = { value: TEXT_FN_DEFAULT_MATCH_END }, ifNotFound = new NotAvailableError()) {
|
|
20835
|
+
const _text = toString(text);
|
|
20836
|
+
const _matchIndex = toNumber(matchIndex, this.locale);
|
|
20837
|
+
const _matchMode = toNumber(matchMode, this.locale);
|
|
20838
|
+
const _matchEnd = toNumber(matchEnd, this.locale);
|
|
20839
|
+
if (_matchIndex === 0) {
|
|
20840
|
+
return new EvaluationError(_t("The instance_num (%s) must not be zero.", _matchIndex));
|
|
20841
|
+
}
|
|
20842
|
+
if (_matchMode !== 0 && _matchMode !== 1) {
|
|
20843
|
+
return new EvaluationError(_t("match_mode should have a value of 0 or 1."));
|
|
20844
|
+
}
|
|
20845
|
+
if (_matchEnd !== 0 && _matchEnd !== 1) {
|
|
20846
|
+
return new EvaluationError(_t("match_end should have a value of 0 or 1."));
|
|
20847
|
+
}
|
|
20848
|
+
const _delimiter = toString(delimiter);
|
|
20849
|
+
if (_delimiter === "") {
|
|
20850
|
+
return Math.sign(_matchIndex) > 0 ? { value: _text } : { value: "" };
|
|
20851
|
+
}
|
|
20852
|
+
const flags = _matchMode === 1 ? "gi" : "g";
|
|
20853
|
+
const pattern = escapeRegExp(_delimiter);
|
|
20854
|
+
const regexp = new RegExp(pattern, flags);
|
|
20855
|
+
let matchIndices = [..._text.matchAll(regexp)].map((match) => match.index + pattern.length);
|
|
20856
|
+
if (_matchIndex < 0) {
|
|
20857
|
+
matchIndices = matchIndices.reverse();
|
|
20858
|
+
}
|
|
20859
|
+
// If _matchEnd, we act like the text is appended by the delimiter (or prepended if negative index)
|
|
20860
|
+
if (_matchEnd && Math.abs(_matchIndex) === matchIndices.length + 1) {
|
|
20861
|
+
return Math.sign(_matchIndex) > 0 ? { value: "" } : { value: _text };
|
|
20862
|
+
}
|
|
20863
|
+
const targetIndex = matchIndices[Math.abs(_matchIndex) - 1];
|
|
20864
|
+
return targetIndex === undefined ? ifNotFound : { value: _text.substring(targetIndex) };
|
|
20865
|
+
},
|
|
20866
|
+
isExported: true,
|
|
20867
|
+
};
|
|
20868
|
+
// -----------------------------------------------------------------------------
|
|
20869
|
+
// TEXTBEFORE
|
|
20870
|
+
// -----------------------------------------------------------------------------
|
|
20871
|
+
const TEXTBEFORE = {
|
|
20872
|
+
description: _t("Returns text that occurs before a given substring or delimiter."),
|
|
20873
|
+
args: [
|
|
20874
|
+
arg("text (string)", _t("The source text.")),
|
|
20875
|
+
arg("delimiter (string)", _t("The substring after which text will be returned.")),
|
|
20876
|
+
arg(`instance_num (number, default=${TEXT_FN_DEFAULT_INSTANCE})`, _t("The desired instance of the delimiter before which we extract the text. A negative number searches from the end.")),
|
|
20877
|
+
arg(`match_mode (number, default=${TEXT_FN_DEFAULT_MATCH_MODE})`, _t("0 = case-sensitive, 1 = case-insensitive.")),
|
|
20878
|
+
arg(`match_end (number, default=${TEXT_FN_DEFAULT_MATCH_END}))`, _t("Whether to match a delimiter against the end of the text.")),
|
|
20879
|
+
arg(`if_not_found (string, default="${CellErrorType.NotAvailable}")`, _t("Value to return if the delimiter is not found.")),
|
|
20880
|
+
],
|
|
20881
|
+
compute: function (text, delimiter, matchIndex = { value: TEXT_FN_DEFAULT_INSTANCE }, matchMode = { value: TEXT_FN_DEFAULT_MATCH_MODE }, matchEnd = { value: TEXT_FN_DEFAULT_MATCH_END }, ifNotFound = new NotAvailableError()) {
|
|
20882
|
+
const _text = toString(text);
|
|
20883
|
+
const _matchIndex = toNumber(matchIndex, this.locale);
|
|
20884
|
+
const _matchMode = toNumber(matchMode, this.locale);
|
|
20885
|
+
const _matchEnd = toNumber(matchEnd, this.locale);
|
|
20886
|
+
if (_matchIndex === 0) {
|
|
20887
|
+
return new EvaluationError(_t("The instance_num (%s) must not be zero.", _matchIndex));
|
|
20888
|
+
}
|
|
20889
|
+
if (_matchMode !== 0 && _matchMode !== 1) {
|
|
20890
|
+
return new EvaluationError(_t("match_mode should have a value of 0 or 1."));
|
|
20891
|
+
}
|
|
20892
|
+
if (_matchEnd !== 0 && _matchEnd !== 1) {
|
|
20893
|
+
return new EvaluationError(_t("match_end should have a value of 0 or 1."));
|
|
20894
|
+
}
|
|
20895
|
+
const _delimiter = toString(delimiter);
|
|
20896
|
+
if (_delimiter === "") {
|
|
20897
|
+
return Math.sign(_matchIndex) > 0 ? { value: "" } : { value: _text };
|
|
20898
|
+
}
|
|
20899
|
+
const flags = _matchMode === 1 ? "gi" : "g";
|
|
20900
|
+
const pattern = escapeRegExp(_delimiter);
|
|
20901
|
+
const regexp = new RegExp(pattern, flags);
|
|
20902
|
+
let matchIndices = [..._text.matchAll(regexp)].map((match) => match.index + pattern.length);
|
|
20903
|
+
if (_matchIndex < 0) {
|
|
20904
|
+
matchIndices = matchIndices.reverse();
|
|
20905
|
+
}
|
|
20906
|
+
// If _matchEnd, we act like the text is appended by the delimiter (or prepended if negative index)
|
|
20907
|
+
if (_matchEnd && Math.abs(_matchIndex) === matchIndices.length + 1) {
|
|
20908
|
+
return Math.sign(_matchIndex) > 0 ? { value: _text } : { value: "" };
|
|
20909
|
+
}
|
|
20910
|
+
const targetIndex = matchIndices[Math.abs(_matchIndex) - 1];
|
|
20911
|
+
return targetIndex === undefined
|
|
20912
|
+
? ifNotFound
|
|
20913
|
+
: { value: _text.substring(0, targetIndex - _delimiter.length) };
|
|
20914
|
+
},
|
|
20915
|
+
isExported: true,
|
|
20916
|
+
};
|
|
20755
20917
|
|
|
20756
20918
|
var text = /*#__PURE__*/Object.freeze({
|
|
20757
20919
|
__proto__: null,
|
|
@@ -20766,12 +20928,15 @@ var text = /*#__PURE__*/Object.freeze({
|
|
|
20766
20928
|
LOWER: LOWER,
|
|
20767
20929
|
MID: MID,
|
|
20768
20930
|
PROPER: PROPER,
|
|
20931
|
+
REGEXEXTRACT: REGEXEXTRACT,
|
|
20769
20932
|
REPLACE: REPLACE,
|
|
20770
20933
|
RIGHT: RIGHT,
|
|
20771
20934
|
SEARCH: SEARCH,
|
|
20772
20935
|
SPLIT: SPLIT,
|
|
20773
20936
|
SUBSTITUTE: SUBSTITUTE,
|
|
20774
20937
|
TEXT: TEXT,
|
|
20938
|
+
TEXTAFTER: TEXTAFTER,
|
|
20939
|
+
TEXTBEFORE: TEXTBEFORE,
|
|
20775
20940
|
TEXTJOIN: TEXTJOIN,
|
|
20776
20941
|
TEXTSPLIT: TEXTSPLIT,
|
|
20777
20942
|
TRIM: TRIM,
|
|
@@ -22775,6 +22940,7 @@ class ChartJsComponent extends Component {
|
|
|
22775
22940
|
this.animationStore = useStore(ChartAnimationStore);
|
|
22776
22941
|
}
|
|
22777
22942
|
onMounted(() => {
|
|
22943
|
+
registerChartJSExtensions();
|
|
22778
22944
|
const runtime = this.chartRuntime;
|
|
22779
22945
|
this.currentRuntime = runtime;
|
|
22780
22946
|
// Note: chartJS modify the runtime in place, so it's important to give it a copy
|
|
@@ -30515,28 +30681,17 @@ class MenuPopover extends Component {
|
|
|
30515
30681
|
}
|
|
30516
30682
|
}
|
|
30517
30683
|
|
|
30518
|
-
class
|
|
30519
|
-
|
|
30520
|
-
|
|
30521
|
-
static props = { figureUI: Object };
|
|
30684
|
+
class ChartDashboardMenuStore extends SpreadsheetStore {
|
|
30685
|
+
chartId;
|
|
30686
|
+
mutators = ["reset"];
|
|
30522
30687
|
originalChartDefinition;
|
|
30523
|
-
|
|
30524
|
-
|
|
30525
|
-
|
|
30526
|
-
|
|
30527
|
-
this.fullScreenFigureStore = useStore(FullScreenChartStore);
|
|
30528
|
-
this.originalChartDefinition = this.env.model.getters.getChartDefinition(this.props.figureUI.id);
|
|
30529
|
-
onWillUpdateProps(({ figureUI }) => {
|
|
30530
|
-
if (figureUI.id !== this.props.figureUI.id) {
|
|
30531
|
-
this.originalChartDefinition = this.env.model.getters.getChartDefinition(figureUI.id);
|
|
30532
|
-
}
|
|
30533
|
-
});
|
|
30534
|
-
}
|
|
30535
|
-
getMenuItems() {
|
|
30536
|
-
return [this.fullScreenMenuItem, ...this.changeChartTypeMenuItems].filter(isDefined);
|
|
30688
|
+
constructor(get, chartId) {
|
|
30689
|
+
super(get);
|
|
30690
|
+
this.chartId = chartId;
|
|
30691
|
+
this.originalChartDefinition = this.getters.getChartDefinition(this.chartId);
|
|
30537
30692
|
}
|
|
30538
30693
|
get changeChartTypeMenuItems() {
|
|
30539
|
-
const definition = this.
|
|
30694
|
+
const definition = this.getters.getChartDefinition(this.chartId);
|
|
30540
30695
|
if (!["line", "bar", "pie"].includes(definition.type)) {
|
|
30541
30696
|
return [];
|
|
30542
30697
|
}
|
|
@@ -30545,27 +30700,19 @@ class ChartDashboardMenu extends Component {
|
|
|
30545
30700
|
return {
|
|
30546
30701
|
id: item.chartType,
|
|
30547
30702
|
label: item.displayName,
|
|
30548
|
-
onClick: () => this.
|
|
30549
|
-
isSelected: item.chartType === this.
|
|
30703
|
+
onClick: () => this.updateType(item.chartType),
|
|
30704
|
+
isSelected: item.chartType === this.getters.getChartDefinition(this.chartId).type,
|
|
30550
30705
|
iconClass: this.getIconClasses(item.chartType),
|
|
30551
30706
|
};
|
|
30552
30707
|
});
|
|
30553
30708
|
}
|
|
30554
|
-
|
|
30555
|
-
|
|
30556
|
-
|
|
30557
|
-
}
|
|
30558
|
-
if (type.includes("line")) {
|
|
30559
|
-
return "fa fa-line-chart";
|
|
30560
|
-
}
|
|
30561
|
-
if (type.includes("pie")) {
|
|
30562
|
-
return "fa fa-pie-chart";
|
|
30563
|
-
}
|
|
30564
|
-
return "";
|
|
30709
|
+
reset(chartId) {
|
|
30710
|
+
this.chartId = chartId;
|
|
30711
|
+
this.originalChartDefinition = this.getters.getChartDefinition(chartId);
|
|
30565
30712
|
}
|
|
30566
|
-
|
|
30567
|
-
const figureId = this.
|
|
30568
|
-
const currentDefinition = this.
|
|
30713
|
+
updateType(type) {
|
|
30714
|
+
const figureId = this.chartId;
|
|
30715
|
+
const currentDefinition = this.getters.getChartDefinition(figureId);
|
|
30569
30716
|
if (currentDefinition.type === type) {
|
|
30570
30717
|
return;
|
|
30571
30718
|
}
|
|
@@ -30576,7 +30723,7 @@ class ChartDashboardMenu extends Component {
|
|
|
30576
30723
|
else {
|
|
30577
30724
|
const newChartInfo = chartSubtypeRegistry.get(type);
|
|
30578
30725
|
const ChartClass = chartRegistry.get(newChartInfo.chartType);
|
|
30579
|
-
const chartCreationContext = this.
|
|
30726
|
+
const chartCreationContext = this.getters.getContextCreationChart(figureId);
|
|
30580
30727
|
if (!chartCreationContext)
|
|
30581
30728
|
return;
|
|
30582
30729
|
definition = {
|
|
@@ -30584,14 +30731,45 @@ class ChartDashboardMenu extends Component {
|
|
|
30584
30731
|
...newChartInfo.subtypeDefinition,
|
|
30585
30732
|
};
|
|
30586
30733
|
}
|
|
30587
|
-
this.
|
|
30734
|
+
this.model.dispatch("UPDATE_CHART", {
|
|
30588
30735
|
definition,
|
|
30589
30736
|
figureId,
|
|
30590
|
-
sheetId: this.
|
|
30737
|
+
sheetId: this.getters.getActiveSheetId(),
|
|
30591
30738
|
});
|
|
30592
30739
|
}
|
|
30593
|
-
|
|
30594
|
-
|
|
30740
|
+
getIconClasses(type) {
|
|
30741
|
+
if (type.includes("bar")) {
|
|
30742
|
+
return "fa fa-bar-chart";
|
|
30743
|
+
}
|
|
30744
|
+
if (type.includes("line")) {
|
|
30745
|
+
return "fa fa-line-chart";
|
|
30746
|
+
}
|
|
30747
|
+
if (type.includes("pie")) {
|
|
30748
|
+
return "fa fa-pie-chart";
|
|
30749
|
+
}
|
|
30750
|
+
return "";
|
|
30751
|
+
}
|
|
30752
|
+
}
|
|
30753
|
+
|
|
30754
|
+
class ChartDashboardMenu extends Component {
|
|
30755
|
+
static template = "o-spreadsheet-ChartDashboardMenu";
|
|
30756
|
+
static components = { MenuPopover };
|
|
30757
|
+
static props = { figureUI: Object };
|
|
30758
|
+
fullScreenFigureStore;
|
|
30759
|
+
store;
|
|
30760
|
+
menuState = useState({ isOpen: false, anchorRect: null, menuItems: [] });
|
|
30761
|
+
setup() {
|
|
30762
|
+
super.setup();
|
|
30763
|
+
this.store = useLocalStore(ChartDashboardMenuStore, this.props.figureUI.id);
|
|
30764
|
+
this.fullScreenFigureStore = useStore(FullScreenChartStore);
|
|
30765
|
+
onWillUpdateProps(({ figureUI }) => {
|
|
30766
|
+
if (figureUI.id !== this.props.figureUI.id) {
|
|
30767
|
+
this.store.reset(figureUI.id);
|
|
30768
|
+
}
|
|
30769
|
+
});
|
|
30770
|
+
}
|
|
30771
|
+
getMenuItems() {
|
|
30772
|
+
return [this.fullScreenMenuItem, ...this.store.changeChartTypeMenuItems].filter(isDefined);
|
|
30595
30773
|
}
|
|
30596
30774
|
get backgroundColor() {
|
|
30597
30775
|
const color = this.env.model.getters.getChartDefinition(this.props.figureUI.id).background;
|
|
@@ -31733,7 +31911,7 @@ criterionEvaluatorRegistry.add("isValueInRange", {
|
|
|
31733
31911
|
}
|
|
31734
31912
|
const criterionValues = getters.getDataValidationRangeValues(sheetId, criterion);
|
|
31735
31913
|
return criterionValues
|
|
31736
|
-
.map((value) => value.toLowerCase())
|
|
31914
|
+
.map((value) => value.value.toLowerCase())
|
|
31737
31915
|
.includes(value.toString().toLowerCase());
|
|
31738
31916
|
},
|
|
31739
31917
|
getErrorString: (criterion) => _t("The value must be a value in the range %s", String(criterion.values[0])),
|
|
@@ -32165,40 +32343,6 @@ function compareContentToSpanElement(content, node) {
|
|
|
32165
32343
|
return sameColor && sameClass && sameContent;
|
|
32166
32344
|
}
|
|
32167
32345
|
|
|
32168
|
-
// -----------------------------------------------------------------------------
|
|
32169
|
-
// Formula Assistant component
|
|
32170
|
-
// -----------------------------------------------------------------------------
|
|
32171
|
-
css /* scss */ `
|
|
32172
|
-
.o-formula-assistant {
|
|
32173
|
-
background: #ffffff;
|
|
32174
|
-
.o-formula-assistant-head {
|
|
32175
|
-
background-color: #f2f2f2;
|
|
32176
|
-
padding: 10px;
|
|
32177
|
-
}
|
|
32178
|
-
.collapsed {
|
|
32179
|
-
transform: rotate(180deg);
|
|
32180
|
-
}
|
|
32181
|
-
.o-formula-assistant-core {
|
|
32182
|
-
border-bottom: 1px solid gray;
|
|
32183
|
-
}
|
|
32184
|
-
.o-formula-assistant-arg-description {
|
|
32185
|
-
font-size: 85%;
|
|
32186
|
-
}
|
|
32187
|
-
.o-formula-assistant-focus {
|
|
32188
|
-
div:first-child,
|
|
32189
|
-
span {
|
|
32190
|
-
color: ${COMPOSER_ASSISTANT_COLOR};
|
|
32191
|
-
text-shadow: 0px 0px 1px ${COMPOSER_ASSISTANT_COLOR};
|
|
32192
|
-
}
|
|
32193
|
-
div:last-child {
|
|
32194
|
-
color: black;
|
|
32195
|
-
}
|
|
32196
|
-
}
|
|
32197
|
-
.o-formula-assistant-gray {
|
|
32198
|
-
color: gray;
|
|
32199
|
-
}
|
|
32200
|
-
}
|
|
32201
|
-
`;
|
|
32202
32346
|
class FunctionDescriptionProvider extends Component {
|
|
32203
32347
|
static template = "o-spreadsheet-FunctionDescriptionProvider";
|
|
32204
32348
|
static props = {
|
|
@@ -51911,16 +52055,16 @@ class ConditionalFormatPreview extends Component {
|
|
|
51911
52055
|
return cssPropertiesToCss(cellStyleToCss(rule.style));
|
|
51912
52056
|
}
|
|
51913
52057
|
else if (rule.type === "ColorScaleRule") {
|
|
51914
|
-
const minColor =
|
|
51915
|
-
const midColor = rule.midpoint ?
|
|
51916
|
-
const maxColor =
|
|
52058
|
+
const minColor = colorNumberToHex(rule.minimum.color);
|
|
52059
|
+
const midColor = rule.midpoint ? colorNumberToHex(rule.midpoint.color) : null;
|
|
52060
|
+
const maxColor = colorNumberToHex(rule.maximum.color);
|
|
51917
52061
|
const baseString = "background-image: linear-gradient(to right, ";
|
|
51918
52062
|
return midColor
|
|
51919
52063
|
? baseString + minColor + ", " + midColor + ", " + maxColor + ")"
|
|
51920
52064
|
: baseString + minColor + ", " + maxColor + ")";
|
|
51921
52065
|
}
|
|
51922
52066
|
else if (rule.type === "DataBarRule") {
|
|
51923
|
-
const color =
|
|
52067
|
+
const color = colorNumberToHex(rule.color);
|
|
51924
52068
|
return `background-image: linear-gradient(to right, ${color} 50%, white 50%)`;
|
|
51925
52069
|
}
|
|
51926
52070
|
return "";
|
|
@@ -52110,7 +52254,8 @@ class ConditionalFormattingEditor extends Component {
|
|
|
52110
52254
|
static props = {
|
|
52111
52255
|
editedCf: Object,
|
|
52112
52256
|
onCancel: Function,
|
|
52113
|
-
|
|
52257
|
+
onExit: Function,
|
|
52258
|
+
isNewCf: Boolean,
|
|
52114
52259
|
};
|
|
52115
52260
|
static components = {
|
|
52116
52261
|
SelectionInput,
|
|
@@ -52127,7 +52272,7 @@ class ConditionalFormattingEditor extends Component {
|
|
|
52127
52272
|
icons = ICONS;
|
|
52128
52273
|
iconSets = ICON_SETS;
|
|
52129
52274
|
getTextDecoration = getTextDecoration;
|
|
52130
|
-
|
|
52275
|
+
colorNumberToHex = colorNumberToHex;
|
|
52131
52276
|
state;
|
|
52132
52277
|
setup() {
|
|
52133
52278
|
this.state = useState({
|
|
@@ -52135,6 +52280,7 @@ class ConditionalFormattingEditor extends Component {
|
|
|
52135
52280
|
currentCFType: this.props.editedCf.rule.type,
|
|
52136
52281
|
ranges: this.props.editedCf.ranges,
|
|
52137
52282
|
rules: this.getDefaultRules(),
|
|
52283
|
+
hasEditedCf: this.props.isNewCf,
|
|
52138
52284
|
});
|
|
52139
52285
|
switch (this.props.editedCf.rule.type) {
|
|
52140
52286
|
case "CellIsRule":
|
|
@@ -52186,6 +52332,9 @@ class ConditionalFormattingEditor extends Component {
|
|
|
52186
52332
|
ranges: ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(sheetId, xc)),
|
|
52187
52333
|
sheetId,
|
|
52188
52334
|
});
|
|
52335
|
+
if (result.isSuccessful) {
|
|
52336
|
+
this.state.hasEditedCf = true;
|
|
52337
|
+
}
|
|
52189
52338
|
const reasons = result.reasons.filter((r) => r !== "NoChanges" /* CommandResult.NoChanges */);
|
|
52190
52339
|
if (!newCf.suppressErrors) {
|
|
52191
52340
|
this.state.errors = reasons;
|
|
@@ -52207,7 +52356,15 @@ class ConditionalFormattingEditor extends Component {
|
|
|
52207
52356
|
onSave() {
|
|
52208
52357
|
const result = this.updateConditionalFormat({});
|
|
52209
52358
|
if (result.length === 0) {
|
|
52210
|
-
this.props.
|
|
52359
|
+
this.props.onExit();
|
|
52360
|
+
}
|
|
52361
|
+
}
|
|
52362
|
+
onCancel() {
|
|
52363
|
+
if (this.state.hasEditedCf) {
|
|
52364
|
+
this.props.onCancel();
|
|
52365
|
+
}
|
|
52366
|
+
else {
|
|
52367
|
+
this.props.onExit();
|
|
52211
52368
|
}
|
|
52212
52369
|
}
|
|
52213
52370
|
getDefaultRules() {
|
|
@@ -52366,9 +52523,9 @@ class ConditionalFormattingEditor extends Component {
|
|
|
52366
52523
|
}
|
|
52367
52524
|
getPreviewGradient() {
|
|
52368
52525
|
const rule = this.state.rules.colorScale;
|
|
52369
|
-
const minColor =
|
|
52370
|
-
const midColor =
|
|
52371
|
-
const maxColor =
|
|
52526
|
+
const minColor = colorNumberToHex(rule.minimum.color);
|
|
52527
|
+
const midColor = colorNumberToHex(rule.midpoint?.color || DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
|
|
52528
|
+
const maxColor = colorNumberToHex(rule.maximum.color);
|
|
52372
52529
|
const baseString = "background-image: linear-gradient(to right, ";
|
|
52373
52530
|
return rule.midpoint === undefined
|
|
52374
52531
|
? baseString + minColor + ", " + maxColor + ")"
|
|
@@ -52376,8 +52533,8 @@ class ConditionalFormattingEditor extends Component {
|
|
|
52376
52533
|
}
|
|
52377
52534
|
getThresholdColor(threshold) {
|
|
52378
52535
|
return threshold
|
|
52379
|
-
?
|
|
52380
|
-
:
|
|
52536
|
+
? colorNumberToHex(threshold.color)
|
|
52537
|
+
: colorNumberToHex(DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
|
|
52381
52538
|
}
|
|
52382
52539
|
onMidpointChange(ev) {
|
|
52383
52540
|
const type = ev.target.value;
|
|
@@ -66601,9 +66758,9 @@ class CustomColorsPlugin extends CoreViewPlugin {
|
|
|
66601
66758
|
formatColors.push(rule.style.fillColor);
|
|
66602
66759
|
}
|
|
66603
66760
|
else if (rule.type === "ColorScaleRule") {
|
|
66604
|
-
formatColors.push(
|
|
66605
|
-
formatColors.push(rule.midpoint ?
|
|
66606
|
-
formatColors.push(
|
|
66761
|
+
formatColors.push(colorNumberToHex(rule.minimum.color));
|
|
66762
|
+
formatColors.push(rule.midpoint ? colorNumberToHex(rule.midpoint.color) : undefined);
|
|
66763
|
+
formatColors.push(colorNumberToHex(rule.maximum.color));
|
|
66607
66764
|
}
|
|
66608
66765
|
}
|
|
66609
66766
|
return formatColors.filter(isDefined);
|
|
@@ -66974,7 +67131,7 @@ class EvaluationConditionalFormatPlugin extends CoreViewPlugin {
|
|
|
66974
67131
|
if (!computedDataBars[col])
|
|
66975
67132
|
computedDataBars[col] = [];
|
|
66976
67133
|
computedDataBars[col][row] = {
|
|
66977
|
-
color:
|
|
67134
|
+
color: colorNumberToHex(color),
|
|
66978
67135
|
percentage: (cell.value * 100) / max,
|
|
66979
67136
|
};
|
|
66980
67137
|
}
|
|
@@ -67103,8 +67260,16 @@ class EvaluationDataValidationPlugin extends CoreViewPlugin {
|
|
|
67103
67260
|
}
|
|
67104
67261
|
getDataValidationRangeValues(sheetId, criterion) {
|
|
67105
67262
|
const range = this.getters.getRangeFromSheetXC(sheetId, String(criterion.values[0]));
|
|
67106
|
-
const
|
|
67107
|
-
|
|
67263
|
+
const values = [];
|
|
67264
|
+
const labelsSet = new Set();
|
|
67265
|
+
for (const p of positions(range.zone)) {
|
|
67266
|
+
const cell = this.getters.getEvaluatedCell({ ...p, sheetId: range.sheetId });
|
|
67267
|
+
if (cell.formattedValue && !labelsSet.has(cell.formattedValue)) {
|
|
67268
|
+
labelsSet.add(cell.formattedValue);
|
|
67269
|
+
values.push({ label: cell.formattedValue, value: cell.value?.toString() || "" });
|
|
67270
|
+
}
|
|
67271
|
+
}
|
|
67272
|
+
return values;
|
|
67108
67273
|
}
|
|
67109
67274
|
isCellValidCheckbox(cellPosition) {
|
|
67110
67275
|
if (!this.getters.isMainCellPosition(cellPosition)) {
|
|
@@ -75726,25 +75891,30 @@ autoCompleteProviders.add("dataValidation", {
|
|
|
75726
75891
|
}
|
|
75727
75892
|
const sheetId = this.composer.currentEditedCell.sheetId;
|
|
75728
75893
|
const values = rule.criterion.type === "isValueInRange"
|
|
75729
|
-
?
|
|
75730
|
-
: rule.criterion.values;
|
|
75894
|
+
? this.getters.getDataValidationRangeValues(sheetId, rule.criterion)
|
|
75895
|
+
: rule.criterion.values.map((value) => ({ label: value, value }));
|
|
75731
75896
|
const isChip = rule.criterion.displayStyle === "chip";
|
|
75732
75897
|
if (!isChip) {
|
|
75733
|
-
return values.map((value) => ({
|
|
75898
|
+
return values.map((value) => ({
|
|
75899
|
+
text: value.value,
|
|
75900
|
+
fuzzySearchKey: value.label,
|
|
75901
|
+
htmlContent: [{ value: value.label }],
|
|
75902
|
+
}));
|
|
75734
75903
|
}
|
|
75735
75904
|
const colors = rule.criterion.colors;
|
|
75736
75905
|
return values.map((value) => {
|
|
75737
|
-
const color = colors?.[value];
|
|
75906
|
+
const color = colors?.[value.value];
|
|
75738
75907
|
return {
|
|
75739
|
-
text: value,
|
|
75908
|
+
text: value.value,
|
|
75740
75909
|
htmlContent: [
|
|
75741
75910
|
{
|
|
75742
|
-
value,
|
|
75911
|
+
value: value.label,
|
|
75743
75912
|
color: color ? chipTextColor(color) : undefined,
|
|
75744
75913
|
backgroundColor: color || GRAY_200,
|
|
75745
75914
|
classes: ["badge rounded-pill fs-6 fw-normal w-100 mt-1 text-start"],
|
|
75746
75915
|
},
|
|
75747
75916
|
],
|
|
75917
|
+
fuzzySearchKey: value.label,
|
|
75748
75918
|
};
|
|
75749
75919
|
});
|
|
75750
75920
|
},
|
|
@@ -79985,7 +80155,6 @@ css /* scss */ `
|
|
|
79985
80155
|
}
|
|
79986
80156
|
}
|
|
79987
80157
|
|
|
79988
|
-
.o-spreadsheet-topbar-wrapper,
|
|
79989
80158
|
.o-spreadsheet-bottombar-wrapper {
|
|
79990
80159
|
z-index: ${ComponentsImportance.ScrollBar + 1};
|
|
79991
80160
|
}
|
|
@@ -80100,7 +80269,6 @@ class Spreadsheet extends Component {
|
|
|
80100
80269
|
this.checkViewportSize();
|
|
80101
80270
|
stores.on("store-updated", this, render);
|
|
80102
80271
|
resizeObserver.observe(this.spreadsheetRef.el);
|
|
80103
|
-
registerChartJSExtensions();
|
|
80104
80272
|
});
|
|
80105
80273
|
onWillUnmount(() => {
|
|
80106
80274
|
this.unbindModelEvents();
|
|
@@ -82746,7 +82914,7 @@ function addDataBarRule(cf, rule) {
|
|
|
82746
82914
|
<dataBar>
|
|
82747
82915
|
<cfvo type="min" val="0"/>
|
|
82748
82916
|
<cfvo type="max" val="100"/>
|
|
82749
|
-
<color rgb="${toXlsxHexColor(
|
|
82917
|
+
<color rgb="${toXlsxHexColor(colorNumberToHex(rule.color))}"/>
|
|
82750
82918
|
</dataBar>
|
|
82751
82919
|
</cfRule>
|
|
82752
82920
|
</conditionalFormatting>
|
|
@@ -82774,7 +82942,7 @@ function addColorScaleRule(cf, rule) {
|
|
|
82774
82942
|
continue;
|
|
82775
82943
|
}
|
|
82776
82944
|
cfValueObject.push(thresholdAttributes(threshold, position));
|
|
82777
|
-
colors.push([["rgb", toXlsxHexColor(
|
|
82945
|
+
colors.push([["rgb", toXlsxHexColor(colorNumberToHex(threshold.color))]]);
|
|
82778
82946
|
}
|
|
82779
82947
|
if (!canExport) {
|
|
82780
82948
|
console.warn("Conditional formats with formula rules are not supported at the moment. The rule is therefore skipped.");
|
|
@@ -84718,6 +84886,8 @@ const components = {
|
|
|
84718
84886
|
WaterfallChartDesignPanel,
|
|
84719
84887
|
ComboChartDesignPanel,
|
|
84720
84888
|
FunnelChartDesignPanel,
|
|
84889
|
+
SunburstChartDesignPanel,
|
|
84890
|
+
TreeMapChartDesignPanel,
|
|
84721
84891
|
ChartTypePicker,
|
|
84722
84892
|
FigureComponent,
|
|
84723
84893
|
MenuPopover,
|
|
@@ -84747,6 +84917,7 @@ const hooks = {
|
|
|
84747
84917
|
};
|
|
84748
84918
|
const stores = {
|
|
84749
84919
|
useStoreProvider,
|
|
84920
|
+
ChartDashboardMenuStore,
|
|
84750
84921
|
DependencyContainer,
|
|
84751
84922
|
CellPopoverStore,
|
|
84752
84923
|
ComposerFocusStore,
|
|
@@ -84785,6 +84956,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
|
|
|
84785
84956
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, ClientDisconnectedError, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, LocalTransportService, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
84786
84957
|
|
|
84787
84958
|
|
|
84788
|
-
__info__.version = "18.5.0-alpha.
|
|
84789
|
-
__info__.date = "2025-
|
|
84790
|
-
__info__.hash = "
|
|
84959
|
+
__info__.version = "18.5.0-alpha.5";
|
|
84960
|
+
__info__.date = "2025-08-04T06:53:29.412Z";
|
|
84961
|
+
__info__.hash = "71c9a36";
|