@odoo/o-spreadsheet 19.1.2 → 19.2.0-alpha.2
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-engine.d.ts +10 -6
- package/dist/o-spreadsheet-engine.esm.js +130 -16
- package/dist/o-spreadsheet-engine.iife.js +130 -16
- package/dist/o-spreadsheet-engine.min.iife.js +312 -312
- package/dist/o-spreadsheet.d.ts +17 -10
- package/dist/o_spreadsheet.css +20 -10
- package/dist/o_spreadsheet.esm.js +678 -589
- package/dist/o_spreadsheet.iife.js +678 -589
- package/dist/o_spreadsheet.min.iife.js +9 -9
- package/dist/o_spreadsheet.xml +97 -103
- package/package.json +2 -2
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 19.
|
|
6
|
-
* @date 2026-01-07T16:21:
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.2.0-alpha.2
|
|
6
|
+
* @date 2026-01-07T16:21:35.251Z
|
|
7
|
+
* @hash ac2fa3e
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -10483,6 +10483,7 @@
|
|
|
10483
10483
|
case "dateIsAfter":
|
|
10484
10484
|
case "dateIsOnOrAfter":
|
|
10485
10485
|
case "dateIsOnOrBefore":
|
|
10486
|
+
case "top10":
|
|
10486
10487
|
rule.values = rule.values.map((v) => changeContentLocale(v));
|
|
10487
10488
|
return rule;
|
|
10488
10489
|
case "beginsWithText":
|
|
@@ -14632,6 +14633,7 @@
|
|
|
14632
14633
|
dateValue: _t("The value must be a date"),
|
|
14633
14634
|
validRange: _t("The value must be a valid range"),
|
|
14634
14635
|
validFormula: _t("The formula must be valid"),
|
|
14636
|
+
positiveNumber: _t("The value must be a positive number"),
|
|
14635
14637
|
},
|
|
14636
14638
|
Errors: {
|
|
14637
14639
|
["InvalidRange" /* CommandResult.InvalidRange */]: _t("The range is invalid."),
|
|
@@ -34020,6 +34022,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34020
34022
|
greaterThanOrEqual: "isGreaterOrEqualTo",
|
|
34021
34023
|
lessThan: "isLessThan",
|
|
34022
34024
|
lessThanOrEqual: "isLessOrEqualTo",
|
|
34025
|
+
top10: "top10",
|
|
34023
34026
|
};
|
|
34024
34027
|
/** Conversion map CF types in XLSX <=> Cf types in o_spreadsheet */
|
|
34025
34028
|
const CF_TYPE_CONVERSION_MAP = {
|
|
@@ -34560,6 +34563,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34560
34563
|
const rule = cf.cfRules[0];
|
|
34561
34564
|
let operator;
|
|
34562
34565
|
const values = [];
|
|
34566
|
+
const cfAdditionalProperties = {};
|
|
34563
34567
|
if (rule.dxfId === undefined &&
|
|
34564
34568
|
!(rule.type === "colorScale" || rule.type === "iconSet" || rule.type === "dataBar"))
|
|
34565
34569
|
continue;
|
|
@@ -34568,7 +34572,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34568
34572
|
case "containsErrors":
|
|
34569
34573
|
case "notContainsErrors":
|
|
34570
34574
|
case "duplicateValues":
|
|
34571
|
-
case "top10":
|
|
34572
34575
|
case "uniqueValues":
|
|
34573
34576
|
case "timePeriod":
|
|
34574
34577
|
// Not supported
|
|
@@ -34619,6 +34622,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34619
34622
|
values.push(prefixFormulaWithEqual(rule.formula[1]));
|
|
34620
34623
|
}
|
|
34621
34624
|
break;
|
|
34625
|
+
case "top10":
|
|
34626
|
+
if (rule.rank === undefined)
|
|
34627
|
+
continue;
|
|
34628
|
+
operator = CF_OPERATOR_TYPE_CONVERSION_MAP[rule.type];
|
|
34629
|
+
values.push(rule.rank.toString());
|
|
34630
|
+
if (rule.percent) {
|
|
34631
|
+
cfAdditionalProperties.isPercent = true;
|
|
34632
|
+
}
|
|
34633
|
+
if (rule.bottom) {
|
|
34634
|
+
cfAdditionalProperties.isBottom = true;
|
|
34635
|
+
}
|
|
34636
|
+
break;
|
|
34622
34637
|
}
|
|
34623
34638
|
if (operator && rule.dxfId !== undefined) {
|
|
34624
34639
|
cfs.push({
|
|
@@ -34629,6 +34644,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34629
34644
|
type: "CellIsRule",
|
|
34630
34645
|
operator: operator,
|
|
34631
34646
|
values: values,
|
|
34647
|
+
...cfAdditionalProperties,
|
|
34632
34648
|
style: convertStyle({ fontStyle: dxfs[rule.dxfId].font, fillStyle: dxfs[rule.dxfId].fill }, warningManager),
|
|
34633
34649
|
},
|
|
34634
34650
|
});
|
|
@@ -34847,6 +34863,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34847
34863
|
return "greaterThanOrEqual";
|
|
34848
34864
|
case "dateIsOnOrBefore":
|
|
34849
34865
|
return "lessThanOrEqual";
|
|
34866
|
+
case "top10":
|
|
34867
|
+
return "top10";
|
|
34850
34868
|
}
|
|
34851
34869
|
}
|
|
34852
34870
|
// -------------------------------------
|
|
@@ -40630,15 +40648,20 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40630
40648
|
getPreview: (criterion) => _t("Value one of: %s", criterion.values.join(", ")),
|
|
40631
40649
|
});
|
|
40632
40650
|
criterionEvaluatorRegistry.add("isValueInRange", {
|
|
40633
|
-
type: "
|
|
40634
|
-
|
|
40651
|
+
type: "isValueInRange",
|
|
40652
|
+
preComputeCriterion: (criterion, criterionRanges, getters) => {
|
|
40653
|
+
if (criterionRanges.length === 0) {
|
|
40654
|
+
return new Set();
|
|
40655
|
+
}
|
|
40656
|
+
const sheetId = criterionRanges[0].sheetId;
|
|
40657
|
+
const criterionValues = getters.getDataValidationRangeValues(sheetId, criterion);
|
|
40658
|
+
return new Set(criterionValues.map((value) => value.value.toString().toLowerCase()));
|
|
40659
|
+
},
|
|
40660
|
+
isValueValid: (value, criterion, valuesSet) => {
|
|
40635
40661
|
if (!value) {
|
|
40636
40662
|
return false;
|
|
40637
40663
|
}
|
|
40638
|
-
|
|
40639
|
-
return criterionValues
|
|
40640
|
-
.map((value) => value.value.toLowerCase())
|
|
40641
|
-
.includes(value.toString().toLowerCase());
|
|
40664
|
+
return valuesSet.has(value.toString().toLowerCase());
|
|
40642
40665
|
},
|
|
40643
40666
|
getErrorString: (criterion) => _t("The value must be a value in the range %s", String(criterion.values[0])),
|
|
40644
40667
|
isCriterionValueValid: (value) => rangeReference.test(value),
|
|
@@ -40715,6 +40738,67 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40715
40738
|
name: _t("Is not empty"),
|
|
40716
40739
|
getPreview: () => _t("Is not empty"),
|
|
40717
40740
|
});
|
|
40741
|
+
criterionEvaluatorRegistry.add("top10", {
|
|
40742
|
+
type: "top10",
|
|
40743
|
+
preComputeCriterion: (criterion, criterionRanges, getters) => {
|
|
40744
|
+
let value = tryToNumber(criterion.values[0], DEFAULT_LOCALE);
|
|
40745
|
+
if (value === undefined || value <= 0) {
|
|
40746
|
+
return undefined;
|
|
40747
|
+
}
|
|
40748
|
+
const numberValues = [];
|
|
40749
|
+
for (const range of criterionRanges) {
|
|
40750
|
+
for (const value of getters.getRangeValues(range)) {
|
|
40751
|
+
if (typeof value === "number") {
|
|
40752
|
+
numberValues.push(value);
|
|
40753
|
+
}
|
|
40754
|
+
}
|
|
40755
|
+
}
|
|
40756
|
+
const sortedValues = numberValues.sort((a, b) => a - b);
|
|
40757
|
+
if (criterion.isPercent) {
|
|
40758
|
+
value = clip(value, 1, 100);
|
|
40759
|
+
}
|
|
40760
|
+
let index = 0;
|
|
40761
|
+
if (criterion.isBottom && !criterion.isPercent) {
|
|
40762
|
+
index = value - 1;
|
|
40763
|
+
}
|
|
40764
|
+
else if (criterion.isBottom && criterion.isPercent) {
|
|
40765
|
+
index = Math.floor((sortedValues.length * value) / 100) - 1;
|
|
40766
|
+
}
|
|
40767
|
+
else if (!criterion.isBottom && criterion.isPercent) {
|
|
40768
|
+
index = sortedValues.length - Math.floor((sortedValues.length * value) / 100);
|
|
40769
|
+
}
|
|
40770
|
+
else {
|
|
40771
|
+
index = sortedValues.length - value;
|
|
40772
|
+
}
|
|
40773
|
+
index = clip(index, 0, sortedValues.length - 1);
|
|
40774
|
+
return sortedValues[index];
|
|
40775
|
+
},
|
|
40776
|
+
isValueValid: (value, criterion, threshold) => {
|
|
40777
|
+
if (typeof value !== "number" || threshold === undefined) {
|
|
40778
|
+
return false;
|
|
40779
|
+
}
|
|
40780
|
+
return criterion.isBottom ? value <= threshold : value >= threshold;
|
|
40781
|
+
},
|
|
40782
|
+
getErrorString: (criterion) => {
|
|
40783
|
+
const args = {
|
|
40784
|
+
value: String(criterion.values[0]),
|
|
40785
|
+
percentSymbol: criterion.isPercent ? "%" : "",
|
|
40786
|
+
};
|
|
40787
|
+
return criterion.isBottom
|
|
40788
|
+
? _t("The value must be in bottom %(value)s%(percentSymbol)s", args)
|
|
40789
|
+
: _t("The value must be in top %(value)s%(percentSymbol)s", args);
|
|
40790
|
+
},
|
|
40791
|
+
isCriterionValueValid: (value) => checkValueIsPositiveNumber(value),
|
|
40792
|
+
criterionValueErrorString: DVTerms.CriterionError.positiveNumber,
|
|
40793
|
+
numberOfValues: () => 1,
|
|
40794
|
+
name: _t("Is in Top/Bottom ranking"),
|
|
40795
|
+
getPreview: (criterion) => {
|
|
40796
|
+
const args = { value: criterion.values[0], percentSymbol: criterion.isPercent ? "%" : "" };
|
|
40797
|
+
return criterion.isBottom
|
|
40798
|
+
? _t("Value is in bottom %(value)s%(percentSymbol)s", args)
|
|
40799
|
+
: _t("Value is in top %(value)s%(percentSymbol)s", args);
|
|
40800
|
+
},
|
|
40801
|
+
});
|
|
40718
40802
|
function getNumberCriterionlocalizedValues(criterion, locale) {
|
|
40719
40803
|
return criterion.values.map((value) => {
|
|
40720
40804
|
return value !== undefined
|
|
@@ -40736,6 +40820,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40736
40820
|
const valueAsNumber = tryToNumber(value, DEFAULT_LOCALE);
|
|
40737
40821
|
return valueAsNumber !== undefined;
|
|
40738
40822
|
}
|
|
40823
|
+
function checkValueIsPositiveNumber(value) {
|
|
40824
|
+
const valueAsNumber = tryToNumber(value, DEFAULT_LOCALE);
|
|
40825
|
+
return valueAsNumber !== undefined && valueAsNumber > 0;
|
|
40826
|
+
}
|
|
40739
40827
|
|
|
40740
40828
|
// -----------------------------------------------------------------------------
|
|
40741
40829
|
// Constants
|
|
@@ -51110,6 +51198,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51110
51198
|
break;
|
|
51111
51199
|
case "CellIsRule":
|
|
51112
51200
|
const formulas = cf.rule.values.map((value) => value.startsWith("=") ? compile(value) : undefined);
|
|
51201
|
+
const evaluator = criterionEvaluatorRegistry.get(cf.rule.operator);
|
|
51202
|
+
const criterion = { ...cf.rule, type: cf.rule.operator };
|
|
51203
|
+
const ranges = cf.ranges.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
51204
|
+
const preComputedCriterion = evaluator.preComputeCriterion?.(criterion, ranges, this.getters);
|
|
51113
51205
|
for (const ref of cf.ranges) {
|
|
51114
51206
|
const zone = this.getters.getRangeFromSheetXC(sheetId, ref).zone;
|
|
51115
51207
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
@@ -51122,7 +51214,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51122
51214
|
}
|
|
51123
51215
|
return value;
|
|
51124
51216
|
});
|
|
51125
|
-
if (this.getRuleResultForTarget(target, { ...cf.rule, values })) {
|
|
51217
|
+
if (this.getRuleResultForTarget(target, { ...cf.rule, values }, preComputedCriterion)) {
|
|
51126
51218
|
if (!computedStyle[col])
|
|
51127
51219
|
computedStyle[col] = [];
|
|
51128
51220
|
// we must combine all the properties of all the CF rules applied to the given cell
|
|
@@ -51285,7 +51377,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51285
51377
|
}
|
|
51286
51378
|
}
|
|
51287
51379
|
}
|
|
51288
|
-
getRuleResultForTarget(target, rule) {
|
|
51380
|
+
getRuleResultForTarget(target, rule, preComputedCriterion) {
|
|
51289
51381
|
const cell = this.getters.getEvaluatedCell(target);
|
|
51290
51382
|
if (cell.type === CellValueType.error) {
|
|
51291
51383
|
return false;
|
|
@@ -51302,11 +51394,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51302
51394
|
return false;
|
|
51303
51395
|
}
|
|
51304
51396
|
const evaluatedCriterion = {
|
|
51397
|
+
...rule,
|
|
51305
51398
|
type: rule.operator,
|
|
51306
51399
|
values: evaluatedCriterionValues.map(toScalar),
|
|
51307
51400
|
dateValue: rule.dateValue || "exactDate",
|
|
51308
51401
|
};
|
|
51309
|
-
return evaluator.isValueValid(cell.value ?? "", evaluatedCriterion,
|
|
51402
|
+
return evaluator.isValueValid(cell.value ?? "", evaluatedCriterion, preComputedCriterion);
|
|
51310
51403
|
}
|
|
51311
51404
|
}
|
|
51312
51405
|
|
|
@@ -51323,17 +51416,20 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51323
51416
|
"isDataValidationInvalid",
|
|
51324
51417
|
];
|
|
51325
51418
|
validationResults = {};
|
|
51419
|
+
criterionPreComputeResult = {};
|
|
51326
51420
|
handle(cmd) {
|
|
51327
51421
|
if (invalidateEvaluationCommands.has(cmd.type) ||
|
|
51328
51422
|
cmd.type === "EVALUATE_CELLS" ||
|
|
51329
51423
|
(cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd))) {
|
|
51330
51424
|
this.validationResults = {};
|
|
51425
|
+
this.criterionPreComputeResult = {};
|
|
51331
51426
|
return;
|
|
51332
51427
|
}
|
|
51333
51428
|
switch (cmd.type) {
|
|
51334
51429
|
case "ADD_DATA_VALIDATION_RULE":
|
|
51335
51430
|
case "REMOVE_DATA_VALIDATION_RULE":
|
|
51336
51431
|
delete this.validationResults[cmd.sheetId];
|
|
51432
|
+
delete this.criterionPreComputeResult[cmd.sheetId];
|
|
51337
51433
|
break;
|
|
51338
51434
|
}
|
|
51339
51435
|
}
|
|
@@ -51476,7 +51572,15 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51476
51572
|
return undefined;
|
|
51477
51573
|
}
|
|
51478
51574
|
const evaluatedCriterion = { ...criterion, values: evaluatedCriterionValues.map(toScalar) };
|
|
51479
|
-
if (
|
|
51575
|
+
if (!this.criterionPreComputeResult[sheetId]) {
|
|
51576
|
+
this.criterionPreComputeResult[sheetId] = {};
|
|
51577
|
+
}
|
|
51578
|
+
let preComputedCriterion = this.criterionPreComputeResult[sheetId][rule.id];
|
|
51579
|
+
if (preComputedCriterion === undefined) {
|
|
51580
|
+
preComputedCriterion = evaluator.preComputeCriterion?.(rule.criterion, rule.ranges, this.getters);
|
|
51581
|
+
this.criterionPreComputeResult[sheetId][rule.id] = preComputedCriterion;
|
|
51582
|
+
}
|
|
51583
|
+
if (evaluator.isValueValid(cellValue, evaluatedCriterion, preComputedCriterion)) {
|
|
51480
51584
|
return undefined;
|
|
51481
51585
|
}
|
|
51482
51586
|
return evaluator.getErrorString(evaluatedCriterion, this.getters, sheetId);
|
|
@@ -57171,6 +57275,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57171
57275
|
if (filterValue.type === "none")
|
|
57172
57276
|
continue;
|
|
57173
57277
|
const evaluator = criterionEvaluatorRegistry.get(filterValue.type);
|
|
57278
|
+
const preComputedCriterion = evaluator.preComputeCriterion?.(filterValue, [filter.filteredRange], this.getters);
|
|
57174
57279
|
const evaluatedCriterionValues = filterValue.values.map((value) => {
|
|
57175
57280
|
if (!value.startsWith("=")) {
|
|
57176
57281
|
return parseLiteral(value, DEFAULT_LOCALE);
|
|
@@ -57188,7 +57293,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57188
57293
|
for (let row = filteredZone.top; row <= filteredZone.bottom; row++) {
|
|
57189
57294
|
const position = { sheetId, col: filter.col, row };
|
|
57190
57295
|
const value = this.getters.getEvaluatedCell(position).value ?? "";
|
|
57191
|
-
if (!evaluator.isValueValid(value, evaluatedCriterion,
|
|
57296
|
+
if (!evaluator.isValueValid(value, evaluatedCriterion, preComputedCriterion)) {
|
|
57192
57297
|
hiddenRows.add(row);
|
|
57193
57298
|
}
|
|
57194
57299
|
}
|
|
@@ -61315,6 +61420,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
61315
61420
|
case undefined:
|
|
61316
61421
|
throw new Error("dateValue should be defined");
|
|
61317
61422
|
}
|
|
61423
|
+
case "top10":
|
|
61424
|
+
return [];
|
|
61318
61425
|
}
|
|
61319
61426
|
}
|
|
61320
61427
|
function cellRuleTypeAttributes(rule) {
|
|
@@ -61347,6 +61454,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
61347
61454
|
case "dateIs":
|
|
61348
61455
|
case "customFormula":
|
|
61349
61456
|
return [["type", "expression"]];
|
|
61457
|
+
case "top10": {
|
|
61458
|
+
return [
|
|
61459
|
+
["type", "top10"],
|
|
61460
|
+
["rank", rule.values[0]],
|
|
61461
|
+
["percent", rule.isPercent ? "1" : "0"],
|
|
61462
|
+
["bottom", rule.isBottom ? "1" : "0"],
|
|
61463
|
+
];
|
|
61464
|
+
}
|
|
61350
61465
|
}
|
|
61351
61466
|
}
|
|
61352
61467
|
function addDataBarRule(cf, rule) {
|
|
@@ -64929,13 +65044,16 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
64929
65044
|
document.body.removeChild(a);
|
|
64930
65045
|
}
|
|
64931
65046
|
/**
|
|
64932
|
-
* Detects
|
|
65047
|
+
* Detects the current browser brand and subsequent rendering engine
|
|
64933
65048
|
*/
|
|
64934
65049
|
function isBrowserFirefox() {
|
|
64935
65050
|
return /Firefox/i.test(navigator.userAgent);
|
|
64936
65051
|
}
|
|
65052
|
+
function isBrowserChrome() {
|
|
65053
|
+
return /Chrome/i.test(navigator.userAgent);
|
|
65054
|
+
}
|
|
64937
65055
|
function isBrowserSafari() {
|
|
64938
|
-
return /Safari/i.test(navigator.userAgent);
|
|
65056
|
+
return !isBrowserChrome() && /Safari/i.test(navigator.userAgent);
|
|
64939
65057
|
}
|
|
64940
65058
|
// Mobile detection
|
|
64941
65059
|
function maxTouchPoints() {
|
|
@@ -65064,6 +65182,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
65064
65182
|
"dateIsAfter",
|
|
65065
65183
|
"dateIsOnOrBefore",
|
|
65066
65184
|
"dateIsOnOrAfter",
|
|
65185
|
+
"top10",
|
|
65067
65186
|
];
|
|
65068
65187
|
const availableConditionalFormatOperators = new Set(cfOperators);
|
|
65069
65188
|
|
|
@@ -73035,6 +73154,26 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
73035
73154
|
}
|
|
73036
73155
|
}
|
|
73037
73156
|
|
|
73157
|
+
class Top10CriterionForm extends CriterionForm {
|
|
73158
|
+
static template = "o-spreadsheet-Top10CriterionForm";
|
|
73159
|
+
static components = { CriterionInput };
|
|
73160
|
+
onValueChanged(value) {
|
|
73161
|
+
const criterion = deepCopy(this.props.criterion);
|
|
73162
|
+
criterion.values[0] = value;
|
|
73163
|
+
this.updateCriterion(criterion);
|
|
73164
|
+
}
|
|
73165
|
+
updateIsBottom(ev) {
|
|
73166
|
+
const criterion = deepCopy(this.props.criterion);
|
|
73167
|
+
criterion.isBottom = ev.target.value === "bottom";
|
|
73168
|
+
this.updateCriterion(criterion);
|
|
73169
|
+
}
|
|
73170
|
+
updateIsPercent(ev) {
|
|
73171
|
+
const criterion = deepCopy(this.props.criterion);
|
|
73172
|
+
criterion.isPercent = ev.target.value === "percent";
|
|
73173
|
+
this.updateCriterion(criterion);
|
|
73174
|
+
}
|
|
73175
|
+
}
|
|
73176
|
+
|
|
73038
73177
|
/**
|
|
73039
73178
|
* Start listening to pointer events and apply the given callbacks.
|
|
73040
73179
|
*
|
|
@@ -74204,6 +74343,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
74204
74343
|
text: 20,
|
|
74205
74344
|
number: 30,
|
|
74206
74345
|
date: 40,
|
|
74346
|
+
relative: 45,
|
|
74207
74347
|
misc: 50,
|
|
74208
74348
|
};
|
|
74209
74349
|
const criterionComponentRegistry = new Registry$1();
|
|
@@ -74381,6 +74521,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
74381
74521
|
category: "misc",
|
|
74382
74522
|
sequence: 6,
|
|
74383
74523
|
});
|
|
74524
|
+
criterionComponentRegistry.add("top10", {
|
|
74525
|
+
type: "top10",
|
|
74526
|
+
component: Top10CriterionForm,
|
|
74527
|
+
category: "relative",
|
|
74528
|
+
sequence: 7,
|
|
74529
|
+
});
|
|
74384
74530
|
function getCriterionMenuItems(callback, availableTypes) {
|
|
74385
74531
|
const items = criterionComponentRegistry
|
|
74386
74532
|
.getAll()
|
|
@@ -76011,7 +76157,17 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
76011
76157
|
// Side panel
|
|
76012
76158
|
//------------------------------------------------------------------------------
|
|
76013
76159
|
const OPEN_CF_SIDEPANEL_ACTION = (env) => {
|
|
76014
|
-
|
|
76160
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
76161
|
+
const zones = env.model.getters.getSelectedZones();
|
|
76162
|
+
const rules = env.model.getters.getConditionalFormats(sheetId);
|
|
76163
|
+
const ruleIds = env.model.getters.getRulesSelection(sheetId, zones);
|
|
76164
|
+
if (ruleIds.length === 1) {
|
|
76165
|
+
return env.openSidePanel("ConditionalFormattingEditor", {
|
|
76166
|
+
cf: rules.find((r) => r.id === ruleIds[0]),
|
|
76167
|
+
isNewCf: false,
|
|
76168
|
+
});
|
|
76169
|
+
}
|
|
76170
|
+
return env.openSidePanel("ConditionalFormatting");
|
|
76015
76171
|
};
|
|
76016
76172
|
const INSERT_LINK = (env) => {
|
|
76017
76173
|
const { col, row } = env.model.getters.getActivePosition();
|
|
@@ -77009,12 +77165,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
77009
77165
|
const zones = env.model.getters.getSelectedZones();
|
|
77010
77166
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
77011
77167
|
const ranges = zones.map((zone) => env.model.getters.getRangeDataFromZone(sheetId, zone));
|
|
77012
|
-
const
|
|
77168
|
+
const ruleId = env.model.uuidGenerator.smallUuid();
|
|
77013
77169
|
env.model.dispatch("ADD_DATA_VALIDATION_RULE", {
|
|
77014
77170
|
ranges,
|
|
77015
77171
|
sheetId,
|
|
77016
77172
|
rule: {
|
|
77017
|
-
id:
|
|
77173
|
+
id: ruleId,
|
|
77018
77174
|
criterion: {
|
|
77019
77175
|
type: "isValueInList",
|
|
77020
77176
|
values: [],
|
|
@@ -77022,16 +77178,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
77022
77178
|
},
|
|
77023
77179
|
},
|
|
77024
77180
|
});
|
|
77025
|
-
const rule = env.model.getters.getDataValidationRule(sheetId,
|
|
77181
|
+
const rule = env.model.getters.getDataValidationRule(sheetId, ruleId);
|
|
77026
77182
|
if (!rule) {
|
|
77027
77183
|
return;
|
|
77028
77184
|
}
|
|
77029
|
-
env.openSidePanel("DataValidationEditor", {
|
|
77030
|
-
rule: localizeDataValidationRule(rule, env.model.getters.getLocale()),
|
|
77031
|
-
onExit: () => {
|
|
77032
|
-
env.replaceSidePanel("DataValidation", "DataValidationEditor");
|
|
77033
|
-
},
|
|
77034
|
-
});
|
|
77185
|
+
env.openSidePanel("DataValidationEditor", { ruleId });
|
|
77035
77186
|
},
|
|
77036
77187
|
isEnabled: (env) => !env.isSmall,
|
|
77037
77188
|
icon: "o-spreadsheet-Icon.INSERT_DROPDOWN",
|
|
@@ -85483,210 +85634,36 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
85483
85634
|
}
|
|
85484
85635
|
}
|
|
85485
85636
|
|
|
85486
|
-
|
|
85487
|
-
|
|
85488
|
-
useHighlights({
|
|
85489
|
-
get highlights() {
|
|
85490
|
-
return hoverState.hovered ? highlightProvider.highlights : [];
|
|
85491
|
-
},
|
|
85492
|
-
});
|
|
85493
|
-
}
|
|
85494
|
-
function useHighlights(highlightProvider) {
|
|
85495
|
-
const stores = useStoreProvider();
|
|
85496
|
-
const store = useLocalStore(HighlightStore);
|
|
85497
|
-
owl.onMounted(() => {
|
|
85498
|
-
store.register(highlightProvider);
|
|
85499
|
-
});
|
|
85500
|
-
let currentHighlights = highlightProvider.highlights;
|
|
85501
|
-
owl.useEffect((highlights) => {
|
|
85502
|
-
if (!deepEquals(highlights, currentHighlights)) {
|
|
85503
|
-
currentHighlights = highlights;
|
|
85504
|
-
stores.trigger("store-updated");
|
|
85505
|
-
}
|
|
85506
|
-
}, () => [highlightProvider.highlights]);
|
|
85507
|
-
}
|
|
85508
|
-
|
|
85509
|
-
class ConditionalFormatPreview extends owl.Component {
|
|
85510
|
-
static template = "o-spreadsheet-ConditionalFormatPreview";
|
|
85511
|
-
icons = ICONS;
|
|
85512
|
-
ref = owl.useRef("cfPreview");
|
|
85513
|
-
setup() {
|
|
85514
|
-
useHighlightsOnHover(this.ref, this);
|
|
85515
|
-
}
|
|
85516
|
-
getPreviewImageStyle() {
|
|
85517
|
-
const rule = this.props.conditionalFormat.rule;
|
|
85518
|
-
if (rule.type === "CellIsRule") {
|
|
85519
|
-
return cssPropertiesToCss(cellStyleToCss(rule.style));
|
|
85520
|
-
}
|
|
85521
|
-
else if (rule.type === "ColorScaleRule") {
|
|
85522
|
-
const minColor = colorNumberToHex(rule.minimum.color);
|
|
85523
|
-
const midColor = rule.midpoint ? colorNumberToHex(rule.midpoint.color) : null;
|
|
85524
|
-
const maxColor = colorNumberToHex(rule.maximum.color);
|
|
85525
|
-
const baseString = "background-image: linear-gradient(to right, ";
|
|
85526
|
-
return midColor
|
|
85527
|
-
? baseString + minColor + ", " + midColor + ", " + maxColor + ")"
|
|
85528
|
-
: baseString + minColor + ", " + maxColor + ")";
|
|
85529
|
-
}
|
|
85530
|
-
else if (rule.type === "DataBarRule") {
|
|
85531
|
-
const barColor = colorNumberToHex(rule.color);
|
|
85532
|
-
const gradient = `background-image: linear-gradient(to right, ${barColor} 50%, white 50%)`;
|
|
85533
|
-
return `${gradient}; color: ${TEXT_BODY};`;
|
|
85534
|
-
}
|
|
85535
|
-
return "";
|
|
85536
|
-
}
|
|
85537
|
-
getDescription() {
|
|
85538
|
-
const cf = this.props.conditionalFormat;
|
|
85539
|
-
switch (cf.rule.type) {
|
|
85540
|
-
case "CellIsRule":
|
|
85541
|
-
return criterionEvaluatorRegistry
|
|
85542
|
-
.get(cf.rule.operator)
|
|
85543
|
-
.getPreview({ ...cf.rule, type: cf.rule.operator }, this.env.model.getters);
|
|
85544
|
-
case "ColorScaleRule":
|
|
85545
|
-
return CfTerms.ColorScale;
|
|
85546
|
-
case "IconSetRule":
|
|
85547
|
-
return CfTerms.IconSet;
|
|
85548
|
-
case "DataBarRule":
|
|
85549
|
-
return CfTerms.DataBar;
|
|
85550
|
-
}
|
|
85551
|
-
}
|
|
85552
|
-
deleteConditionalFormat() {
|
|
85553
|
-
this.env.model.dispatch("REMOVE_CONDITIONAL_FORMAT", {
|
|
85554
|
-
id: this.props.conditionalFormat.id,
|
|
85555
|
-
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
85556
|
-
});
|
|
85557
|
-
}
|
|
85558
|
-
onMouseDown(event) {
|
|
85559
|
-
this.props.onMouseDown(event);
|
|
85560
|
-
}
|
|
85561
|
-
get highlights() {
|
|
85562
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
85563
|
-
return this.props.conditionalFormat.ranges.map((range) => ({
|
|
85564
|
-
range: this.env.model.getters.getRangeFromSheetXC(sheetId, range),
|
|
85565
|
-
color: HIGHLIGHT_COLOR,
|
|
85566
|
-
fillAlpha: 0.06,
|
|
85567
|
-
}));
|
|
85568
|
-
}
|
|
85569
|
-
}
|
|
85570
|
-
ConditionalFormatPreview.props = {
|
|
85571
|
-
conditionalFormat: Object,
|
|
85572
|
-
onPreviewClick: Function,
|
|
85573
|
-
onMouseDown: Function,
|
|
85574
|
-
class: String,
|
|
85575
|
-
};
|
|
85576
|
-
|
|
85577
|
-
class ConditionalFormatPreviewList extends owl.Component {
|
|
85578
|
-
static template = "o-spreadsheet-ConditionalFormatPreviewList";
|
|
85579
|
-
static props = {
|
|
85580
|
-
conditionalFormats: Array,
|
|
85581
|
-
onPreviewClick: Function,
|
|
85582
|
-
onAddConditionalFormat: Function,
|
|
85583
|
-
};
|
|
85584
|
-
static components = { ConditionalFormatPreview };
|
|
85585
|
-
icons = ICONS;
|
|
85586
|
-
dragAndDrop = useDragAndDropListItems();
|
|
85587
|
-
cfListRef = owl.useRef("cfList");
|
|
85588
|
-
setup() {
|
|
85589
|
-
owl.onWillUpdateProps((nextProps) => {
|
|
85590
|
-
if (!deepEquals(this.props.conditionalFormats, nextProps.conditionalFormats)) {
|
|
85591
|
-
this.dragAndDrop.cancel();
|
|
85592
|
-
}
|
|
85593
|
-
});
|
|
85594
|
-
}
|
|
85595
|
-
getPreviewDivStyle(cf) {
|
|
85596
|
-
return this.dragAndDrop.itemsStyle[cf.id] || "";
|
|
85597
|
-
}
|
|
85598
|
-
onPreviewMouseDown(cf, event) {
|
|
85599
|
-
if (event.button !== 0)
|
|
85600
|
-
return;
|
|
85601
|
-
const previewRects = Array.from(this.cfListRef.el.children).map((previewEl) => getBoundingRectAsPOJO(previewEl));
|
|
85602
|
-
const items = this.props.conditionalFormats.map((cf, index) => ({
|
|
85603
|
-
id: cf.id,
|
|
85604
|
-
size: previewRects[index].height,
|
|
85605
|
-
position: previewRects[index].y,
|
|
85606
|
-
}));
|
|
85607
|
-
this.dragAndDrop.start("vertical", {
|
|
85608
|
-
draggedItemId: cf.id,
|
|
85609
|
-
initialMousePosition: event.clientY,
|
|
85610
|
-
items: items,
|
|
85611
|
-
scrollableContainerEl: this.cfListRef.el,
|
|
85612
|
-
onDragEnd: (cfId, finalIndex) => this.onDragEnd(cfId, finalIndex),
|
|
85613
|
-
});
|
|
85614
|
-
}
|
|
85615
|
-
onDragEnd(cfId, finalIndex) {
|
|
85616
|
-
const originalIndex = this.props.conditionalFormats.findIndex((sheet) => sheet.id === cfId);
|
|
85617
|
-
const delta = originalIndex - finalIndex;
|
|
85618
|
-
if (delta !== 0) {
|
|
85619
|
-
this.env.model.dispatch("CHANGE_CONDITIONAL_FORMAT_PRIORITY", {
|
|
85620
|
-
cfId,
|
|
85621
|
-
delta,
|
|
85622
|
-
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
85623
|
-
});
|
|
85624
|
-
}
|
|
85625
|
-
}
|
|
85626
|
-
}
|
|
85627
|
-
|
|
85628
|
-
class ConditionalFormattingEditor extends owl.Component {
|
|
85629
|
-
static template = "o-spreadsheet-ConditionalFormattingEditor";
|
|
85630
|
-
static props = {
|
|
85631
|
-
editedCf: Object,
|
|
85632
|
-
onCancel: Function,
|
|
85633
|
-
onExit: Function,
|
|
85634
|
-
isNewCf: Boolean,
|
|
85635
|
-
};
|
|
85636
|
-
static components = {
|
|
85637
|
-
SelectionInput,
|
|
85638
|
-
IconPicker,
|
|
85639
|
-
ColorPickerWidget,
|
|
85640
|
-
ConditionalFormatPreviewList,
|
|
85641
|
-
Section,
|
|
85642
|
-
RoundColorPicker,
|
|
85643
|
-
StandaloneComposer,
|
|
85644
|
-
BadgeSelection,
|
|
85645
|
-
ValidationMessages,
|
|
85646
|
-
SelectMenu,
|
|
85647
|
-
};
|
|
85637
|
+
class ConditionalFormattingEditorStore extends SpreadsheetStore {
|
|
85638
|
+
mutators = ["updateConditionalFormat", "closeMenus"];
|
|
85648
85639
|
icons = ICONS;
|
|
85649
85640
|
iconSets = ICON_SETS;
|
|
85650
|
-
getTextDecoration = getTextDecoration;
|
|
85651
|
-
colorNumberToHex = colorNumberToHex;
|
|
85652
85641
|
state;
|
|
85653
|
-
|
|
85642
|
+
cfId;
|
|
85643
|
+
constructor(get, cf, isNewCf) {
|
|
85644
|
+
super(get);
|
|
85645
|
+
this.cfId = cf.id;
|
|
85654
85646
|
this.state = owl.useState({
|
|
85655
85647
|
errors: [],
|
|
85656
|
-
currentCFType:
|
|
85657
|
-
ranges:
|
|
85648
|
+
currentCFType: cf.rule.type,
|
|
85649
|
+
ranges: cf.ranges,
|
|
85658
85650
|
rules: this.getDefaultRules(),
|
|
85659
|
-
hasEditedCf:
|
|
85651
|
+
hasEditedCf: isNewCf,
|
|
85660
85652
|
});
|
|
85661
|
-
switch (
|
|
85653
|
+
switch (cf.rule.type) {
|
|
85662
85654
|
case "CellIsRule":
|
|
85663
|
-
this.state.rules.cellIs =
|
|
85655
|
+
this.state.rules.cellIs = cf.rule;
|
|
85664
85656
|
break;
|
|
85665
85657
|
case "ColorScaleRule":
|
|
85666
|
-
this.state.rules.colorScale =
|
|
85658
|
+
this.state.rules.colorScale = cf.rule;
|
|
85667
85659
|
break;
|
|
85668
85660
|
case "IconSetRule":
|
|
85669
|
-
this.state.rules.iconSet =
|
|
85661
|
+
this.state.rules.iconSet = cf.rule;
|
|
85670
85662
|
break;
|
|
85671
85663
|
case "DataBarRule":
|
|
85672
|
-
this.state.rules.dataBar =
|
|
85664
|
+
this.state.rules.dataBar = cf.rule;
|
|
85673
85665
|
break;
|
|
85674
85666
|
}
|
|
85675
|
-
owl.useExternalListener(window, "click", this.closeMenus);
|
|
85676
|
-
}
|
|
85677
|
-
get isRangeValid() {
|
|
85678
|
-
return this.state.errors.includes("EmptyRange" /* CommandResult.EmptyRange */);
|
|
85679
|
-
}
|
|
85680
|
-
get errorMessages() {
|
|
85681
|
-
return this.state.errors.map((error) => CfTerms.Errors[error] || CfTerms.Errors.Unexpected);
|
|
85682
|
-
}
|
|
85683
|
-
get cfTypesValues() {
|
|
85684
|
-
return [
|
|
85685
|
-
{ value: "CellIsRule", label: _t("Single color") },
|
|
85686
|
-
{ value: "ColorScaleRule", label: _t("Color scale") },
|
|
85687
|
-
{ value: "IconSetRule", label: _t("Icon set") },
|
|
85688
|
-
{ value: "DataBarRule", label: _t("Data bar") },
|
|
85689
|
-
];
|
|
85690
85667
|
}
|
|
85691
85668
|
updateConditionalFormat(newCf) {
|
|
85692
85669
|
const ranges = newCf.ranges || this.state.ranges;
|
|
@@ -85695,17 +85672,17 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
85695
85672
|
if (!newCf.suppressErrors) {
|
|
85696
85673
|
this.state.errors = ["InvalidRange" /* CommandResult.InvalidRange */];
|
|
85697
85674
|
}
|
|
85698
|
-
return
|
|
85675
|
+
return;
|
|
85699
85676
|
}
|
|
85700
|
-
const sheetId = this.
|
|
85701
|
-
const locale = this.
|
|
85677
|
+
const sheetId = this.model.getters.getActiveSheetId();
|
|
85678
|
+
const locale = this.model.getters.getLocale();
|
|
85702
85679
|
const rule = newCf.rule || this.getEditedRule(this.state.currentCFType);
|
|
85703
|
-
const result = this.
|
|
85680
|
+
const result = this.model.dispatch("ADD_CONDITIONAL_FORMAT", {
|
|
85704
85681
|
cf: {
|
|
85682
|
+
id: this.cfId,
|
|
85705
85683
|
rule: canonicalizeCFRule(rule, locale),
|
|
85706
|
-
id: this.props.editedCf.id,
|
|
85707
85684
|
},
|
|
85708
|
-
ranges: ranges.map((xc) => this.
|
|
85685
|
+
ranges: ranges.map((xc) => this.model.getters.getRangeDataFromXc(sheetId, xc)),
|
|
85709
85686
|
sheetId,
|
|
85710
85687
|
});
|
|
85711
85688
|
if (result.isSuccessful) {
|
|
@@ -85715,71 +85692,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
85715
85692
|
if (!newCf.suppressErrors) {
|
|
85716
85693
|
this.state.errors = reasons;
|
|
85717
85694
|
}
|
|
85718
|
-
return reasons;
|
|
85719
85695
|
}
|
|
85720
|
-
|
|
85721
|
-
|
|
85722
|
-
case "CellIsRule":
|
|
85723
|
-
return this.state.rules.cellIs;
|
|
85724
|
-
case "ColorScaleRule":
|
|
85725
|
-
return this.state.rules.colorScale;
|
|
85726
|
-
case "IconSetRule":
|
|
85727
|
-
return this.state.rules.iconSet;
|
|
85728
|
-
case "DataBarRule":
|
|
85729
|
-
return this.state.rules.dataBar;
|
|
85730
|
-
}
|
|
85696
|
+
get isRangeValid() {
|
|
85697
|
+
return this.state.errors.includes("EmptyRange" /* CommandResult.EmptyRange */);
|
|
85731
85698
|
}
|
|
85732
|
-
|
|
85733
|
-
|
|
85734
|
-
if (result.length === 0) {
|
|
85735
|
-
this.props.onExit();
|
|
85736
|
-
}
|
|
85699
|
+
get errorMessages() {
|
|
85700
|
+
return this.state.errors.map((error) => CfTerms.Errors[error] || CfTerms.Errors.Unexpected);
|
|
85737
85701
|
}
|
|
85738
|
-
|
|
85739
|
-
|
|
85740
|
-
this.props.onCancel();
|
|
85741
|
-
}
|
|
85742
|
-
else {
|
|
85743
|
-
this.props.onExit();
|
|
85744
|
-
}
|
|
85702
|
+
onRangeUpdate(ranges) {
|
|
85703
|
+
this.state.ranges = ranges;
|
|
85745
85704
|
}
|
|
85746
|
-
|
|
85747
|
-
|
|
85748
|
-
cellIs: {
|
|
85749
|
-
type: "CellIsRule",
|
|
85750
|
-
operator: "isNotEmpty",
|
|
85751
|
-
values: [],
|
|
85752
|
-
style: { fillColor: "#b6d7a8" },
|
|
85753
|
-
},
|
|
85754
|
-
colorScale: {
|
|
85755
|
-
type: "ColorScaleRule",
|
|
85756
|
-
minimum: { type: "value", color: hexaToInt("EFF7FF") },
|
|
85757
|
-
midpoint: undefined,
|
|
85758
|
-
maximum: { type: "value", color: 0x6aa84f },
|
|
85759
|
-
},
|
|
85760
|
-
iconSet: {
|
|
85761
|
-
type: "IconSetRule",
|
|
85762
|
-
icons: {
|
|
85763
|
-
upper: "arrowGood",
|
|
85764
|
-
middle: "arrowNeutral",
|
|
85765
|
-
lower: "arrowBad",
|
|
85766
|
-
},
|
|
85767
|
-
upperInflectionPoint: {
|
|
85768
|
-
type: "percentage",
|
|
85769
|
-
value: "66",
|
|
85770
|
-
operator: "gt",
|
|
85771
|
-
},
|
|
85772
|
-
lowerInflectionPoint: {
|
|
85773
|
-
type: "percentage",
|
|
85774
|
-
value: "33",
|
|
85775
|
-
operator: "gt",
|
|
85776
|
-
},
|
|
85777
|
-
},
|
|
85778
|
-
dataBar: {
|
|
85779
|
-
type: "DataBarRule",
|
|
85780
|
-
color: 0xd9ead3,
|
|
85781
|
-
},
|
|
85782
|
-
};
|
|
85705
|
+
onRangeConfirmed() {
|
|
85706
|
+
this.updateConditionalFormat({ ranges: this.state.ranges });
|
|
85783
85707
|
}
|
|
85784
85708
|
changeRuleType(ruleType) {
|
|
85785
85709
|
if (this.state.currentCFType === ruleType) {
|
|
@@ -85789,34 +85713,45 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
85789
85713
|
this.state.currentCFType = ruleType;
|
|
85790
85714
|
this.updateConditionalFormat({ rule: this.getEditedRule(ruleType), suppressErrors: true });
|
|
85791
85715
|
}
|
|
85792
|
-
|
|
85793
|
-
|
|
85794
|
-
|
|
85795
|
-
|
|
85796
|
-
|
|
85797
|
-
|
|
85798
|
-
|
|
85799
|
-
|
|
85800
|
-
|
|
85801
|
-
|
|
85802
|
-
const isSelected = this.state.openedMenu === menu;
|
|
85803
|
-
this.closeMenus();
|
|
85804
|
-
if (!isSelected) {
|
|
85805
|
-
this.state.openedMenu = menu;
|
|
85716
|
+
getEditedRule(ruleType) {
|
|
85717
|
+
switch (ruleType) {
|
|
85718
|
+
case "CellIsRule":
|
|
85719
|
+
return this.state.rules.cellIs;
|
|
85720
|
+
case "ColorScaleRule":
|
|
85721
|
+
return this.state.rules.colorScale;
|
|
85722
|
+
case "IconSetRule":
|
|
85723
|
+
return this.state.rules.iconSet;
|
|
85724
|
+
case "DataBarRule":
|
|
85725
|
+
return this.state.rules.dataBar;
|
|
85806
85726
|
}
|
|
85807
85727
|
}
|
|
85808
|
-
closeMenus() {
|
|
85809
|
-
this.state.openedMenu = undefined;
|
|
85810
|
-
}
|
|
85811
85728
|
/*****************************************************************************
|
|
85812
85729
|
* Cell Is Rule
|
|
85813
85730
|
****************************************************************************/
|
|
85814
|
-
get
|
|
85815
|
-
return (
|
|
85816
|
-
this.state.errors.includes("ValueCellIsInvalidFormula" /* CommandResult.ValueCellIsInvalidFormula */));
|
|
85731
|
+
get cfCriterionMenuItems() {
|
|
85732
|
+
return getCriterionMenuItems((type) => this.editOperator(type), availableConditionalFormatOperators);
|
|
85817
85733
|
}
|
|
85818
|
-
get
|
|
85819
|
-
return this.state.
|
|
85734
|
+
get selectedCriterionName() {
|
|
85735
|
+
return criterionEvaluatorRegistry.get(this.state.rules.cellIs.operator).name;
|
|
85736
|
+
}
|
|
85737
|
+
get criterionComponent() {
|
|
85738
|
+
return criterionComponentRegistry.get(this.state.rules.cellIs.operator).component;
|
|
85739
|
+
}
|
|
85740
|
+
get genericCriterion() {
|
|
85741
|
+
return {
|
|
85742
|
+
...this.state.rules.cellIs,
|
|
85743
|
+
type: this.state.rules.cellIs.operator,
|
|
85744
|
+
};
|
|
85745
|
+
}
|
|
85746
|
+
onRuleValuesChanged(criterion) {
|
|
85747
|
+
const newRule = {
|
|
85748
|
+
...criterion,
|
|
85749
|
+
operator: criterion.type,
|
|
85750
|
+
type: "CellIsRule",
|
|
85751
|
+
style: this.state.rules.cellIs.style,
|
|
85752
|
+
};
|
|
85753
|
+
this.state.rules.cellIs = newRule;
|
|
85754
|
+
this.updateConditionalFormat({ rule: newRule });
|
|
85820
85755
|
}
|
|
85821
85756
|
toggleStyle(tool) {
|
|
85822
85757
|
const style = this.state.rules.cellIs.style;
|
|
@@ -85824,18 +85759,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
85824
85759
|
this.updateConditionalFormat({ rule: this.state.rules.cellIs });
|
|
85825
85760
|
this.closeMenus();
|
|
85826
85761
|
}
|
|
85827
|
-
onKeydown(event) {
|
|
85828
|
-
if (event.key === "F4") {
|
|
85829
|
-
const target = event.target;
|
|
85830
|
-
const update = cycleFixedReference({ start: target.selectionStart ?? 0, end: target.selectionEnd ?? 0 }, target.value, this.env.model.getters.getLocale());
|
|
85831
|
-
if (!update) {
|
|
85832
|
-
return;
|
|
85833
|
-
}
|
|
85834
|
-
target.value = update.content;
|
|
85835
|
-
target.setSelectionRange(update.selection.start, update.selection.end);
|
|
85836
|
-
target.dispatchEvent(new Event("input"));
|
|
85837
|
-
}
|
|
85838
|
-
}
|
|
85839
85762
|
setColor(target, color) {
|
|
85840
85763
|
this.state.rules.cellIs.style[target] = color;
|
|
85841
85764
|
this.updateConditionalFormat({ rule: this.state.rules.cellIs });
|
|
@@ -85849,62 +85772,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
85849
85772
|
this.updateConditionalFormat({ rule: this.state.rules.cellIs, suppressErrors: true });
|
|
85850
85773
|
this.closeMenus();
|
|
85851
85774
|
}
|
|
85852
|
-
get cfCriterionMenuItems() {
|
|
85853
|
-
return getCriterionMenuItems((type) => this.editOperator(type), availableConditionalFormatOperators);
|
|
85854
|
-
}
|
|
85855
|
-
get selectedCriterionName() {
|
|
85856
|
-
return criterionEvaluatorRegistry.get(this.state.rules.cellIs.operator).name;
|
|
85857
|
-
}
|
|
85858
|
-
get criterionComponent() {
|
|
85859
|
-
return criterionComponentRegistry.get(this.state.rules.cellIs.operator).component;
|
|
85860
|
-
}
|
|
85861
|
-
get genericCriterion() {
|
|
85862
|
-
return {
|
|
85863
|
-
type: this.state.rules.cellIs.operator,
|
|
85864
|
-
values: this.state.rules.cellIs.values,
|
|
85865
|
-
dateValue: this.state.rules.cellIs.dateValue,
|
|
85866
|
-
};
|
|
85867
|
-
}
|
|
85868
|
-
onRuleValuesChanged(rule) {
|
|
85869
|
-
this.state.rules.cellIs.values = rule.values;
|
|
85870
|
-
this.state.rules.cellIs.dateValue = rule.dateValue;
|
|
85871
|
-
this.updateConditionalFormat({
|
|
85872
|
-
rule: { ...this.state.rules.cellIs, values: rule.values, dateValue: rule.dateValue },
|
|
85873
|
-
});
|
|
85874
|
-
}
|
|
85875
85775
|
/*****************************************************************************
|
|
85876
85776
|
* Color Scale Rule
|
|
85877
85777
|
****************************************************************************/
|
|
85878
|
-
|
|
85879
|
-
switch (threshold) {
|
|
85880
|
-
case "minimum":
|
|
85881
|
-
return (this.state.errors.includes("MinInvalidFormula" /* CommandResult.MinInvalidFormula */) ||
|
|
85882
|
-
this.state.errors.includes("MinBiggerThanMid" /* CommandResult.MinBiggerThanMid */) ||
|
|
85883
|
-
this.state.errors.includes("MinBiggerThanMax" /* CommandResult.MinBiggerThanMax */) ||
|
|
85884
|
-
this.state.errors.includes("MinNaN" /* CommandResult.MinNaN */));
|
|
85885
|
-
case "midpoint":
|
|
85886
|
-
return (this.state.errors.includes("MidInvalidFormula" /* CommandResult.MidInvalidFormula */) ||
|
|
85887
|
-
this.state.errors.includes("MidNaN" /* CommandResult.MidNaN */) ||
|
|
85888
|
-
this.state.errors.includes("MidBiggerThanMax" /* CommandResult.MidBiggerThanMax */));
|
|
85889
|
-
case "maximum":
|
|
85890
|
-
return (this.state.errors.includes("MaxInvalidFormula" /* CommandResult.MaxInvalidFormula */) ||
|
|
85891
|
-
this.state.errors.includes("MaxNaN" /* CommandResult.MaxNaN */));
|
|
85892
|
-
default:
|
|
85893
|
-
return false;
|
|
85894
|
-
}
|
|
85895
|
-
}
|
|
85896
|
-
setColorScaleColor(target, color) {
|
|
85897
|
-
if (!isColorValid(color)) {
|
|
85898
|
-
return;
|
|
85899
|
-
}
|
|
85900
|
-
const point = this.state.rules.colorScale[target];
|
|
85901
|
-
if (point) {
|
|
85902
|
-
point.color = colorToNumber(color);
|
|
85903
|
-
}
|
|
85904
|
-
this.updateConditionalFormat({ rule: this.state.rules.colorScale });
|
|
85905
|
-
this.closeMenus();
|
|
85906
|
-
}
|
|
85907
|
-
getColorScalePreviewStyle() {
|
|
85778
|
+
get previewGradient() {
|
|
85908
85779
|
const rule = this.state.rules.colorScale;
|
|
85909
85780
|
const minColor = colorNumberToHex(rule.minimum.color);
|
|
85910
85781
|
const midColor = colorNumberToHex(rule.midpoint?.color || DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
|
|
@@ -85918,13 +85789,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
85918
85789
|
color: "#000",
|
|
85919
85790
|
});
|
|
85920
85791
|
}
|
|
85921
|
-
|
|
85922
|
-
return threshold
|
|
85923
|
-
? colorNumberToHex(threshold.color)
|
|
85924
|
-
: colorNumberToHex(DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
|
|
85925
|
-
}
|
|
85926
|
-
onMidpointChange(ev) {
|
|
85927
|
-
const type = ev.target.value;
|
|
85792
|
+
onMidpointChange(type) {
|
|
85928
85793
|
const rule = this.state.rules.colorScale;
|
|
85929
85794
|
if (type === "none") {
|
|
85930
85795
|
rule.midpoint = undefined;
|
|
@@ -85947,23 +85812,20 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
85947
85812
|
this.state.rules.colorScale[threshold].value = value;
|
|
85948
85813
|
this.updateConditionalFormat({ rule: this.state.rules.colorScale });
|
|
85949
85814
|
}
|
|
85815
|
+
setColorScaleColor(target, color) {
|
|
85816
|
+
if (!isColorValid(color)) {
|
|
85817
|
+
return;
|
|
85818
|
+
}
|
|
85819
|
+
const point = this.state.rules.colorScale[target];
|
|
85820
|
+
if (point) {
|
|
85821
|
+
point.color = colorToNumber(color);
|
|
85822
|
+
}
|
|
85823
|
+
this.updateConditionalFormat({ rule: this.state.rules.colorScale });
|
|
85824
|
+
this.closeMenus();
|
|
85825
|
+
}
|
|
85950
85826
|
/*****************************************************************************
|
|
85951
85827
|
* Icon Set
|
|
85952
85828
|
****************************************************************************/
|
|
85953
|
-
isInflectionPointInvalid(inflectionPoint) {
|
|
85954
|
-
switch (inflectionPoint) {
|
|
85955
|
-
case "lowerInflectionPoint":
|
|
85956
|
-
return (this.state.errors.includes("ValueLowerInflectionNaN" /* CommandResult.ValueLowerInflectionNaN */) ||
|
|
85957
|
-
this.state.errors.includes("ValueLowerInvalidFormula" /* CommandResult.ValueLowerInvalidFormula */) ||
|
|
85958
|
-
this.state.errors.includes("LowerBiggerThanUpper" /* CommandResult.LowerBiggerThanUpper */));
|
|
85959
|
-
case "upperInflectionPoint":
|
|
85960
|
-
return (this.state.errors.includes("ValueUpperInflectionNaN" /* CommandResult.ValueUpperInflectionNaN */) ||
|
|
85961
|
-
this.state.errors.includes("ValueUpperInvalidFormula" /* CommandResult.ValueUpperInvalidFormula */) ||
|
|
85962
|
-
this.state.errors.includes("LowerBiggerThanUpper" /* CommandResult.LowerBiggerThanUpper */));
|
|
85963
|
-
default:
|
|
85964
|
-
return true;
|
|
85965
|
-
}
|
|
85966
|
-
}
|
|
85967
85829
|
reverseIcons() {
|
|
85968
85830
|
const icons = this.state.rules.iconSet.icons;
|
|
85969
85831
|
const upper = icons.upper;
|
|
@@ -85990,12 +85852,176 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
85990
85852
|
this.state.rules.iconSet[inflectionPoint].value = value;
|
|
85991
85853
|
this.updateConditionalFormat({ rule: this.state.rules.iconSet });
|
|
85992
85854
|
}
|
|
85993
|
-
setInflectionType(inflectionPoint, type
|
|
85855
|
+
setInflectionType(inflectionPoint, type) {
|
|
85994
85856
|
this.state.rules.iconSet[inflectionPoint].type = type;
|
|
85995
85857
|
this.updateConditionalFormat({ rule: this.state.rules.iconSet, suppressErrors: true });
|
|
85996
85858
|
}
|
|
85859
|
+
/*****************************************************************************
|
|
85860
|
+
* DataBar
|
|
85861
|
+
****************************************************************************/
|
|
85862
|
+
get rangeValues() {
|
|
85863
|
+
return [this.state.rules.dataBar.rangeValues || ""];
|
|
85864
|
+
}
|
|
85865
|
+
updateDataBarColor(color) {
|
|
85866
|
+
if (!isColorValid(color)) {
|
|
85867
|
+
return;
|
|
85868
|
+
}
|
|
85869
|
+
this.state.rules.dataBar.color = Number.parseInt(color.slice(1), 16);
|
|
85870
|
+
this.updateConditionalFormat({ rule: this.state.rules.dataBar });
|
|
85871
|
+
}
|
|
85872
|
+
onDataBarRangeUpdate(ranges) {
|
|
85873
|
+
this.state.rules.dataBar.rangeValues = ranges[0];
|
|
85874
|
+
}
|
|
85875
|
+
onDataBarRangeChange() {
|
|
85876
|
+
this.updateConditionalFormat({ rule: this.state.rules.dataBar });
|
|
85877
|
+
}
|
|
85878
|
+
/*****************************************************************************
|
|
85879
|
+
* Common
|
|
85880
|
+
****************************************************************************/
|
|
85881
|
+
toggleMenu(menu) {
|
|
85882
|
+
const isSelected = this.state.openedMenu === menu;
|
|
85883
|
+
this.closeMenus();
|
|
85884
|
+
if (!isSelected) {
|
|
85885
|
+
this.state.openedMenu = menu;
|
|
85886
|
+
}
|
|
85887
|
+
}
|
|
85888
|
+
closeMenus() {
|
|
85889
|
+
this.state.openedMenu = undefined;
|
|
85890
|
+
}
|
|
85891
|
+
getDefaultRules() {
|
|
85892
|
+
return {
|
|
85893
|
+
cellIs: {
|
|
85894
|
+
type: "CellIsRule",
|
|
85895
|
+
operator: "isNotEmpty",
|
|
85896
|
+
values: [],
|
|
85897
|
+
style: { fillColor: "#b6d7a8" },
|
|
85898
|
+
},
|
|
85899
|
+
colorScale: {
|
|
85900
|
+
type: "ColorScaleRule",
|
|
85901
|
+
minimum: { type: "value", color: hexaToInt("EFF7FF") },
|
|
85902
|
+
midpoint: undefined,
|
|
85903
|
+
maximum: { type: "value", color: 0x6aa84f },
|
|
85904
|
+
},
|
|
85905
|
+
iconSet: {
|
|
85906
|
+
type: "IconSetRule",
|
|
85907
|
+
icons: {
|
|
85908
|
+
upper: "arrowGood",
|
|
85909
|
+
middle: "arrowNeutral",
|
|
85910
|
+
lower: "arrowBad",
|
|
85911
|
+
},
|
|
85912
|
+
upperInflectionPoint: {
|
|
85913
|
+
type: "percentage",
|
|
85914
|
+
value: "66",
|
|
85915
|
+
operator: "gt",
|
|
85916
|
+
},
|
|
85917
|
+
lowerInflectionPoint: {
|
|
85918
|
+
type: "percentage",
|
|
85919
|
+
value: "33",
|
|
85920
|
+
operator: "gt",
|
|
85921
|
+
},
|
|
85922
|
+
},
|
|
85923
|
+
dataBar: {
|
|
85924
|
+
type: "DataBarRule",
|
|
85925
|
+
color: 0xd9ead3,
|
|
85926
|
+
},
|
|
85927
|
+
};
|
|
85928
|
+
}
|
|
85929
|
+
}
|
|
85930
|
+
|
|
85931
|
+
class ConditionalFormattingEditor extends owl.Component {
|
|
85932
|
+
static template = "o-spreadsheet-ConditionalFormattingEditor";
|
|
85933
|
+
static components = {
|
|
85934
|
+
SelectionInput,
|
|
85935
|
+
IconPicker,
|
|
85936
|
+
ColorPickerWidget,
|
|
85937
|
+
Section,
|
|
85938
|
+
RoundColorPicker,
|
|
85939
|
+
StandaloneComposer,
|
|
85940
|
+
BadgeSelection,
|
|
85941
|
+
ValidationMessages,
|
|
85942
|
+
SelectMenu,
|
|
85943
|
+
};
|
|
85944
|
+
static props = { cf: Object, isNewCf: Boolean, onCloseSidePanel: Function };
|
|
85945
|
+
getTextDecoration = getTextDecoration;
|
|
85946
|
+
colorNumberToHex = colorNumberToHex;
|
|
85947
|
+
activeSheetId;
|
|
85948
|
+
store;
|
|
85949
|
+
setup() {
|
|
85950
|
+
this.activeSheetId = this.env.model.getters.getActiveSheetId();
|
|
85951
|
+
this.store = useLocalStore(ConditionalFormattingEditorStore, deepCopy(this.props.cf), this.props.isNewCf);
|
|
85952
|
+
owl.useEffect((sheetId, isCfRemoved) => {
|
|
85953
|
+
if (this.activeSheetId !== sheetId || isCfRemoved) {
|
|
85954
|
+
this.env.replaceSidePanel("ConditionalFormatting", `ConditionalFormattingEditor_${this.props.cf.id}`);
|
|
85955
|
+
}
|
|
85956
|
+
}, () => [this.env.model.getters.getActiveSheetId(), this.isEditedCfRemoved]);
|
|
85957
|
+
owl.useExternalListener(window, "click", () => this.store.closeMenus());
|
|
85958
|
+
}
|
|
85959
|
+
get isEditedCfRemoved() {
|
|
85960
|
+
return !Boolean(this.env.model.getters
|
|
85961
|
+
.getConditionalFormats(this.activeSheetId)
|
|
85962
|
+
.find((cf) => cf.id === this.props.cf.id));
|
|
85963
|
+
}
|
|
85964
|
+
get cfTypesValues() {
|
|
85965
|
+
return [
|
|
85966
|
+
{ value: "CellIsRule", label: _t("Single color") },
|
|
85967
|
+
{ value: "ColorScaleRule", label: _t("Color scale") },
|
|
85968
|
+
{ value: "IconSetRule", label: _t("Icon set") },
|
|
85969
|
+
{ value: "DataBarRule", label: _t("Data bar") },
|
|
85970
|
+
];
|
|
85971
|
+
}
|
|
85972
|
+
onSave() {
|
|
85973
|
+
this.store.updateConditionalFormat({});
|
|
85974
|
+
const isSuccessful = this.store.state.errors.length === 0;
|
|
85975
|
+
if (isSuccessful) {
|
|
85976
|
+
this.env.replaceSidePanel("ConditionalFormatting", `ConditionalFormattingEditor_${this.props.cf.id}`);
|
|
85977
|
+
}
|
|
85978
|
+
}
|
|
85979
|
+
onCancel() {
|
|
85980
|
+
if (this.store.state.hasEditedCf) {
|
|
85981
|
+
if (this.props.isNewCf) {
|
|
85982
|
+
this.env.model.dispatch("REMOVE_CONDITIONAL_FORMAT", {
|
|
85983
|
+
sheetId: this.activeSheetId,
|
|
85984
|
+
id: this.props.cf.id,
|
|
85985
|
+
});
|
|
85986
|
+
}
|
|
85987
|
+
else {
|
|
85988
|
+
this.env.model.dispatch("ADD_CONDITIONAL_FORMAT", {
|
|
85989
|
+
cf: this.props.cf,
|
|
85990
|
+
ranges: this.props.cf.ranges.map((range) => this.env.model.getters.getRangeDataFromXc(this.activeSheetId, range)),
|
|
85991
|
+
sheetId: this.activeSheetId,
|
|
85992
|
+
});
|
|
85993
|
+
}
|
|
85994
|
+
}
|
|
85995
|
+
this.env.replaceSidePanel("ConditionalFormatting", `ConditionalFormattingEditor_${this.props.cf.id}`);
|
|
85996
|
+
}
|
|
85997
|
+
/*****************************************************************************
|
|
85998
|
+
* Color Scale Rule
|
|
85999
|
+
****************************************************************************/
|
|
86000
|
+
getThresholdColor(threshold) {
|
|
86001
|
+
return threshold
|
|
86002
|
+
? colorNumberToHex(threshold.color)
|
|
86003
|
+
: colorNumberToHex(DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
|
|
86004
|
+
}
|
|
86005
|
+
isValueInvalid(threshold) {
|
|
86006
|
+
const errors = this.store.state.errors;
|
|
86007
|
+
switch (threshold) {
|
|
86008
|
+
case "minimum":
|
|
86009
|
+
return (errors.includes("MinInvalidFormula" /* CommandResult.MinInvalidFormula */) ||
|
|
86010
|
+
errors.includes("MinBiggerThanMid" /* CommandResult.MinBiggerThanMid */) ||
|
|
86011
|
+
errors.includes("MinBiggerThanMax" /* CommandResult.MinBiggerThanMax */) ||
|
|
86012
|
+
errors.includes("MinNaN" /* CommandResult.MinNaN */));
|
|
86013
|
+
case "midpoint":
|
|
86014
|
+
return (errors.includes("MidInvalidFormula" /* CommandResult.MidInvalidFormula */) ||
|
|
86015
|
+
errors.includes("MidNaN" /* CommandResult.MidNaN */) ||
|
|
86016
|
+
errors.includes("MidBiggerThanMax" /* CommandResult.MidBiggerThanMax */));
|
|
86017
|
+
case "maximum":
|
|
86018
|
+
return (errors.includes("MaxInvalidFormula" /* CommandResult.MaxInvalidFormula */) || errors.includes("MaxNaN" /* CommandResult.MaxNaN */));
|
|
86019
|
+
default:
|
|
86020
|
+
return false;
|
|
86021
|
+
}
|
|
86022
|
+
}
|
|
85997
86023
|
getColorScaleComposerProps(thresholdType) {
|
|
85998
|
-
const threshold = this.state.rules.colorScale[thresholdType];
|
|
86024
|
+
const threshold = this.store.state.rules.colorScale[thresholdType];
|
|
85999
86025
|
if (!threshold) {
|
|
86000
86026
|
throw new Error("Threshold not found");
|
|
86001
86027
|
}
|
|
@@ -86003,103 +86029,153 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
86003
86029
|
return {
|
|
86004
86030
|
onConfirm: (str) => {
|
|
86005
86031
|
threshold.value = str;
|
|
86006
|
-
this.updateConditionalFormat({ rule: this.state.rules.colorScale });
|
|
86032
|
+
this.store.updateConditionalFormat({ rule: this.store.state.rules.colorScale });
|
|
86007
86033
|
},
|
|
86008
86034
|
composerContent: threshold.value || "",
|
|
86009
86035
|
placeholder: _t("Formula"),
|
|
86010
86036
|
defaultStatic: true,
|
|
86011
86037
|
invalid: isInvalid,
|
|
86012
86038
|
class: "o-sidePanel-composer",
|
|
86013
|
-
defaultRangeSheetId: this.
|
|
86039
|
+
defaultRangeSheetId: this.activeSheetId,
|
|
86014
86040
|
};
|
|
86015
86041
|
}
|
|
86042
|
+
/*****************************************************************************
|
|
86043
|
+
* Icon Set
|
|
86044
|
+
****************************************************************************/
|
|
86045
|
+
isInflectionPointInvalid(inflectionPoint) {
|
|
86046
|
+
const errors = this.store.state.errors;
|
|
86047
|
+
switch (inflectionPoint) {
|
|
86048
|
+
case "lowerInflectionPoint":
|
|
86049
|
+
return (errors.includes("ValueLowerInflectionNaN" /* CommandResult.ValueLowerInflectionNaN */) ||
|
|
86050
|
+
errors.includes("ValueLowerInvalidFormula" /* CommandResult.ValueLowerInvalidFormula */) ||
|
|
86051
|
+
errors.includes("LowerBiggerThanUpper" /* CommandResult.LowerBiggerThanUpper */));
|
|
86052
|
+
case "upperInflectionPoint":
|
|
86053
|
+
return (errors.includes("ValueUpperInflectionNaN" /* CommandResult.ValueUpperInflectionNaN */) ||
|
|
86054
|
+
errors.includes("ValueUpperInvalidFormula" /* CommandResult.ValueUpperInvalidFormula */) ||
|
|
86055
|
+
errors.includes("LowerBiggerThanUpper" /* CommandResult.LowerBiggerThanUpper */));
|
|
86056
|
+
default:
|
|
86057
|
+
return true;
|
|
86058
|
+
}
|
|
86059
|
+
}
|
|
86016
86060
|
getColorIconSetComposerProps(inflectionPoint) {
|
|
86017
|
-
const inflection = this.state.rules.iconSet[inflectionPoint];
|
|
86061
|
+
const inflection = this.store.state.rules.iconSet[inflectionPoint];
|
|
86018
86062
|
const isInvalid = this.isInflectionPointInvalid(inflectionPoint);
|
|
86019
86063
|
return {
|
|
86020
86064
|
onConfirm: (str) => {
|
|
86021
86065
|
inflection.value = str;
|
|
86022
|
-
this.updateConditionalFormat({ rule: this.state.rules.iconSet });
|
|
86066
|
+
this.store.updateConditionalFormat({ rule: this.store.state.rules.iconSet });
|
|
86023
86067
|
},
|
|
86024
86068
|
composerContent: inflection.value || "",
|
|
86025
86069
|
placeholder: _t("Formula"),
|
|
86026
86070
|
defaultStatic: true,
|
|
86027
86071
|
invalid: isInvalid,
|
|
86028
86072
|
class: "o-sidePanel-composer",
|
|
86029
|
-
defaultRangeSheetId: this.
|
|
86073
|
+
defaultRangeSheetId: this.activeSheetId,
|
|
86030
86074
|
};
|
|
86031
86075
|
}
|
|
86032
|
-
|
|
86033
|
-
|
|
86034
|
-
|
|
86035
|
-
|
|
86036
|
-
|
|
86076
|
+
}
|
|
86077
|
+
|
|
86078
|
+
function useHighlightsOnHover(ref, highlightProvider) {
|
|
86079
|
+
const hoverState = useHoveredElement(ref);
|
|
86080
|
+
useHighlights({
|
|
86081
|
+
get highlights() {
|
|
86082
|
+
return hoverState.hovered ? highlightProvider.highlights : [];
|
|
86083
|
+
},
|
|
86084
|
+
});
|
|
86085
|
+
}
|
|
86086
|
+
function useHighlights(highlightProvider) {
|
|
86087
|
+
const stores = useStoreProvider();
|
|
86088
|
+
const store = useLocalStore(HighlightStore);
|
|
86089
|
+
owl.onMounted(() => {
|
|
86090
|
+
store.register(highlightProvider);
|
|
86091
|
+
});
|
|
86092
|
+
let currentHighlights = highlightProvider.highlights;
|
|
86093
|
+
owl.useEffect((highlights) => {
|
|
86094
|
+
if (!deepEquals(highlights, currentHighlights)) {
|
|
86095
|
+
currentHighlights = highlights;
|
|
86096
|
+
stores.trigger("store-updated");
|
|
86097
|
+
}
|
|
86098
|
+
}, () => [highlightProvider.highlights]);
|
|
86099
|
+
}
|
|
86100
|
+
|
|
86101
|
+
class ConditionalFormatPreview extends owl.Component {
|
|
86102
|
+
static template = "o-spreadsheet-ConditionalFormatPreview";
|
|
86103
|
+
static props = {
|
|
86104
|
+
conditionalFormat: Object,
|
|
86105
|
+
onMouseDown: Function,
|
|
86106
|
+
class: String,
|
|
86107
|
+
};
|
|
86108
|
+
icons = ICONS;
|
|
86109
|
+
ref = owl.useRef("cfPreview");
|
|
86110
|
+
setup() {
|
|
86111
|
+
useHighlightsOnHover(this.ref, this);
|
|
86037
86112
|
}
|
|
86038
|
-
|
|
86039
|
-
|
|
86040
|
-
|
|
86113
|
+
get previewImageStyle() {
|
|
86114
|
+
const rule = this.props.conditionalFormat.rule;
|
|
86115
|
+
if (rule.type === "CellIsRule") {
|
|
86116
|
+
return cssPropertiesToCss(cellStyleToCss(rule.style));
|
|
86041
86117
|
}
|
|
86042
|
-
|
|
86043
|
-
|
|
86118
|
+
else if (rule.type === "ColorScaleRule") {
|
|
86119
|
+
const minColor = colorNumberToHex(rule.minimum.color);
|
|
86120
|
+
const midColor = rule.midpoint ? colorNumberToHex(rule.midpoint.color) : null;
|
|
86121
|
+
const maxColor = colorNumberToHex(rule.maximum.color);
|
|
86122
|
+
const baseString = "background-image: linear-gradient(to right, ";
|
|
86123
|
+
return midColor
|
|
86124
|
+
? baseString + minColor + ", " + midColor + ", " + maxColor + ")"
|
|
86125
|
+
: baseString + minColor + ", " + maxColor + ")";
|
|
86126
|
+
}
|
|
86127
|
+
else if (rule.type === "DataBarRule") {
|
|
86128
|
+
const barColor = colorNumberToHex(rule.color);
|
|
86129
|
+
const gradient = `background-image: linear-gradient(to right, ${barColor} 50%, white 50%)`;
|
|
86130
|
+
return `${gradient}; color: ${TEXT_BODY};`;
|
|
86131
|
+
}
|
|
86132
|
+
return "";
|
|
86044
86133
|
}
|
|
86045
|
-
|
|
86046
|
-
this.
|
|
86134
|
+
get description() {
|
|
86135
|
+
const cf = this.props.conditionalFormat;
|
|
86136
|
+
switch (cf.rule.type) {
|
|
86137
|
+
case "CellIsRule":
|
|
86138
|
+
return criterionEvaluatorRegistry
|
|
86139
|
+
.get(cf.rule.operator)
|
|
86140
|
+
.getPreview({ ...cf.rule, type: cf.rule.operator }, this.env.model.getters);
|
|
86141
|
+
case "ColorScaleRule":
|
|
86142
|
+
return CfTerms.ColorScale;
|
|
86143
|
+
case "IconSetRule":
|
|
86144
|
+
return CfTerms.IconSet;
|
|
86145
|
+
case "DataBarRule":
|
|
86146
|
+
return CfTerms.DataBar;
|
|
86147
|
+
}
|
|
86047
86148
|
}
|
|
86048
|
-
|
|
86049
|
-
|
|
86149
|
+
get highlights() {
|
|
86150
|
+
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
86151
|
+
return this.props.conditionalFormat.ranges.map((range) => ({
|
|
86152
|
+
range: this.env.model.getters.getRangeFromSheetXC(sheetId, range),
|
|
86153
|
+
color: HIGHLIGHT_COLOR,
|
|
86154
|
+
fillAlpha: 0.06,
|
|
86155
|
+
}));
|
|
86156
|
+
}
|
|
86157
|
+
editConditionalFormat() {
|
|
86158
|
+
this.env.replaceSidePanel("ConditionalFormattingEditor", "ConditionalFormatting", {
|
|
86159
|
+
cf: this.props.conditionalFormat,
|
|
86160
|
+
isNewCf: false,
|
|
86161
|
+
});
|
|
86162
|
+
}
|
|
86163
|
+
deleteConditionalFormat() {
|
|
86164
|
+
this.env.model.dispatch("REMOVE_CONDITIONAL_FORMAT", {
|
|
86165
|
+
id: this.props.conditionalFormat.id,
|
|
86166
|
+
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
86167
|
+
});
|
|
86050
86168
|
}
|
|
86051
86169
|
}
|
|
86052
86170
|
|
|
86053
|
-
class
|
|
86054
|
-
static template = "o-spreadsheet-
|
|
86171
|
+
class ConditionalFormatPreviewList extends owl.Component {
|
|
86172
|
+
static template = "o-spreadsheet-ConditionalFormatPreviewList";
|
|
86055
86173
|
static props = {
|
|
86056
|
-
selection: { type: Object, optional: true },
|
|
86057
86174
|
onCloseSidePanel: Function,
|
|
86058
86175
|
};
|
|
86059
|
-
static components = {
|
|
86060
|
-
|
|
86061
|
-
|
|
86062
|
-
Section,
|
|
86063
|
-
};
|
|
86064
|
-
activeSheetId;
|
|
86065
|
-
originalEditedCf = undefined;
|
|
86066
|
-
state = owl.useState({
|
|
86067
|
-
mode: "list",
|
|
86068
|
-
});
|
|
86069
|
-
setup() {
|
|
86070
|
-
this.activeSheetId = this.env.model.getters.getActiveSheetId();
|
|
86071
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
86072
|
-
const rules = this.env.model.getters.getRulesSelection(sheetId, this.props.selection || []);
|
|
86073
|
-
if (rules.length === 1) {
|
|
86074
|
-
const cf = this.conditionalFormats.find((c) => c.id === rules[0]);
|
|
86075
|
-
if (cf) {
|
|
86076
|
-
this.editConditionalFormat(cf);
|
|
86077
|
-
}
|
|
86078
|
-
}
|
|
86079
|
-
owl.onWillUpdateProps((nextProps) => {
|
|
86080
|
-
const newActiveSheetId = this.env.model.getters.getActiveSheetId();
|
|
86081
|
-
if (newActiveSheetId !== this.activeSheetId) {
|
|
86082
|
-
this.activeSheetId = newActiveSheetId;
|
|
86083
|
-
this.switchToList();
|
|
86084
|
-
}
|
|
86085
|
-
else if (nextProps.selection !== this.props.selection) {
|
|
86086
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
86087
|
-
const rules = this.env.model.getters.getRulesSelection(sheetId, nextProps.selection || []);
|
|
86088
|
-
if (rules.length === 1) {
|
|
86089
|
-
const cf = this.conditionalFormats.find((c) => c.id === rules[0]);
|
|
86090
|
-
if (cf) {
|
|
86091
|
-
this.editConditionalFormat(cf);
|
|
86092
|
-
}
|
|
86093
|
-
}
|
|
86094
|
-
else {
|
|
86095
|
-
this.switchToList();
|
|
86096
|
-
}
|
|
86097
|
-
}
|
|
86098
|
-
else if (!this.editedCF) {
|
|
86099
|
-
this.switchToList();
|
|
86100
|
-
}
|
|
86101
|
-
});
|
|
86102
|
-
}
|
|
86176
|
+
static components = { ConditionalFormatPreview };
|
|
86177
|
+
dragAndDrop = useDragAndDropListItems();
|
|
86178
|
+
cfListRef = owl.useRef("cfList");
|
|
86103
86179
|
get conditionalFormats() {
|
|
86104
86180
|
const cfs = this.env.model.getters.getConditionalFormats(this.env.model.getters.getActiveSheetId());
|
|
86105
86181
|
return cfs.map((cf) => ({
|
|
@@ -86107,66 +86183,129 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
86107
86183
|
rule: localizeCFRule(cf.rule, this.env.model.getters.getLocale()),
|
|
86108
86184
|
}));
|
|
86109
86185
|
}
|
|
86110
|
-
|
|
86111
|
-
this.
|
|
86112
|
-
|
|
86113
|
-
|
|
86186
|
+
getPreviewDivStyle(cf) {
|
|
86187
|
+
return this.dragAndDrop.itemsStyle[cf.id] || "";
|
|
86188
|
+
}
|
|
86189
|
+
onPreviewMouseDown(cf, event) {
|
|
86190
|
+
if (event.button !== 0)
|
|
86191
|
+
return;
|
|
86192
|
+
const previewRects = Array.from(this.cfListRef.el.children).map((previewEl) => getBoundingRectAsPOJO(previewEl));
|
|
86193
|
+
const items = this.conditionalFormats.map((cf, index) => ({
|
|
86194
|
+
id: cf.id,
|
|
86195
|
+
size: previewRects[index].height,
|
|
86196
|
+
position: previewRects[index].y,
|
|
86197
|
+
}));
|
|
86198
|
+
this.dragAndDrop.start("vertical", {
|
|
86199
|
+
draggedItemId: cf.id,
|
|
86200
|
+
initialMousePosition: event.clientY,
|
|
86201
|
+
items: items,
|
|
86202
|
+
scrollableContainerEl: this.cfListRef.el,
|
|
86203
|
+
onDragEnd: (cfId, finalIndex) => this.onDragEnd(cfId, finalIndex),
|
|
86204
|
+
});
|
|
86114
86205
|
}
|
|
86115
|
-
|
|
86116
|
-
const
|
|
86206
|
+
onAddConditionalFormat() {
|
|
86207
|
+
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
86208
|
+
const zones = this.env.model.getters.getSelectedZones();
|
|
86209
|
+
const cf = {
|
|
86210
|
+
id: this.env.model.uuidGenerator.smallUuid(),
|
|
86211
|
+
rule: {
|
|
86212
|
+
type: "CellIsRule",
|
|
86213
|
+
operator: "isNotEmpty",
|
|
86214
|
+
style: { fillColor: "#b6d7a8" },
|
|
86215
|
+
values: [],
|
|
86216
|
+
},
|
|
86217
|
+
};
|
|
86117
86218
|
this.env.model.dispatch("ADD_CONDITIONAL_FORMAT", {
|
|
86118
|
-
|
|
86119
|
-
ranges: this.env.model.getters
|
|
86120
|
-
|
|
86121
|
-
|
|
86219
|
+
cf,
|
|
86220
|
+
ranges: zones.map((zone) => this.env.model.getters.getRangeDataFromZone(sheetId, zone)),
|
|
86221
|
+
sheetId,
|
|
86222
|
+
});
|
|
86223
|
+
return this.env.replaceSidePanel("ConditionalFormattingEditor", "ConditionalFormatting", {
|
|
86122
86224
|
cf: {
|
|
86123
|
-
|
|
86124
|
-
|
|
86125
|
-
type: "CellIsRule",
|
|
86126
|
-
operator: "isNotEmpty",
|
|
86127
|
-
style: { fillColor: "#b6d7a8" },
|
|
86128
|
-
values: [],
|
|
86129
|
-
},
|
|
86225
|
+
...cf,
|
|
86226
|
+
ranges: zones.map((zone) => zoneToXc(this.env.model.getters.getUnboundedZone(sheetId, zone))),
|
|
86130
86227
|
},
|
|
86228
|
+
isNewCf: true,
|
|
86131
86229
|
});
|
|
86132
|
-
this.state.editedCfId = cfId;
|
|
86133
|
-
this.state.mode = "edit";
|
|
86134
|
-
this.originalEditedCf = undefined;
|
|
86135
86230
|
}
|
|
86136
|
-
|
|
86137
|
-
this.
|
|
86138
|
-
|
|
86139
|
-
|
|
86140
|
-
|
|
86141
|
-
|
|
86142
|
-
|
|
86143
|
-
|
|
86144
|
-
sheetId: this.activeSheetId,
|
|
86145
|
-
ranges: this.originalEditedCf.ranges.map((range) => this.env.model.getters.getRangeDataFromXc(this.activeSheetId, range)),
|
|
86146
|
-
cf: this.originalEditedCf,
|
|
86147
|
-
});
|
|
86148
|
-
}
|
|
86149
|
-
else if (this.state.editedCfId) {
|
|
86150
|
-
this.env.model.dispatch("REMOVE_CONDITIONAL_FORMAT", {
|
|
86151
|
-
sheetId: this.activeSheetId,
|
|
86152
|
-
id: this.state.editedCfId,
|
|
86231
|
+
onDragEnd(cfId, finalIndex) {
|
|
86232
|
+
const originalIndex = this.conditionalFormats.findIndex((sheet) => sheet.id === cfId);
|
|
86233
|
+
const delta = originalIndex - finalIndex;
|
|
86234
|
+
if (delta !== 0) {
|
|
86235
|
+
this.env.model.dispatch("CHANGE_CONDITIONAL_FORMAT_PRIORITY", {
|
|
86236
|
+
cfId,
|
|
86237
|
+
delta,
|
|
86238
|
+
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
86153
86239
|
});
|
|
86154
86240
|
}
|
|
86155
|
-
this.switchToList();
|
|
86156
86241
|
}
|
|
86157
|
-
|
|
86158
|
-
|
|
86242
|
+
}
|
|
86243
|
+
|
|
86244
|
+
class DataValidationPreview extends owl.Component {
|
|
86245
|
+
static template = "o-spreadsheet-DataValidationPreview";
|
|
86246
|
+
static props = {
|
|
86247
|
+
rule: Object,
|
|
86248
|
+
};
|
|
86249
|
+
ref = owl.useRef("dvPreview");
|
|
86250
|
+
setup() {
|
|
86251
|
+
useHighlightsOnHover(this.ref, this);
|
|
86252
|
+
}
|
|
86253
|
+
onPreviewClick() {
|
|
86254
|
+
this.env.replaceSidePanel("DataValidationEditor", "DataValidation", {
|
|
86255
|
+
ruleId: this.props.rule.id,
|
|
86256
|
+
});
|
|
86257
|
+
}
|
|
86258
|
+
deleteDataValidation() {
|
|
86259
|
+
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
86260
|
+
this.env.model.dispatch("REMOVE_DATA_VALIDATION_RULE", { sheetId, id: this.props.rule.id });
|
|
86261
|
+
}
|
|
86262
|
+
get highlights() {
|
|
86263
|
+
return this.props.rule.ranges.map((range) => ({
|
|
86264
|
+
range,
|
|
86265
|
+
color: HIGHLIGHT_COLOR,
|
|
86266
|
+
fillAlpha: 0.06,
|
|
86267
|
+
}));
|
|
86268
|
+
}
|
|
86269
|
+
get rangesString() {
|
|
86270
|
+
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
86271
|
+
return this.props.rule.ranges
|
|
86272
|
+
.map((range) => this.env.model.getters.getRangeString(range, sheetId))
|
|
86273
|
+
.join(", ");
|
|
86274
|
+
}
|
|
86275
|
+
get descriptionString() {
|
|
86276
|
+
return criterionEvaluatorRegistry
|
|
86277
|
+
.get(this.props.rule.criterion.type)
|
|
86278
|
+
.getPreview(this.props.rule.criterion, this.env.model.getters);
|
|
86279
|
+
}
|
|
86280
|
+
}
|
|
86281
|
+
|
|
86282
|
+
class DataValidationPanel extends owl.Component {
|
|
86283
|
+
static template = "o-spreadsheet-DataValidationPanel";
|
|
86284
|
+
static props = {
|
|
86285
|
+
onCloseSidePanel: Function,
|
|
86286
|
+
};
|
|
86287
|
+
static components = { DataValidationPreview };
|
|
86288
|
+
addDataValidationRule() {
|
|
86289
|
+
this.env.replaceSidePanel("DataValidationEditor", "DataValidation", {
|
|
86290
|
+
ruleId: this.env.model.uuidGenerator.smallUuid(),
|
|
86291
|
+
});
|
|
86292
|
+
}
|
|
86293
|
+
localizeDVRule(rule) {
|
|
86294
|
+
if (!rule)
|
|
86295
|
+
return rule;
|
|
86296
|
+
const locale = this.env.model.getters.getLocale();
|
|
86297
|
+
return localizeDataValidationRule(rule, locale);
|
|
86298
|
+
}
|
|
86299
|
+
get validationRules() {
|
|
86300
|
+
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
86301
|
+
return this.env.model.getters.getDataValidationRules(sheetId);
|
|
86159
86302
|
}
|
|
86160
86303
|
}
|
|
86161
86304
|
|
|
86162
86305
|
class DataValidationEditor extends owl.Component {
|
|
86163
86306
|
static template = "o-spreadsheet-DataValidationEditor";
|
|
86164
86307
|
static components = { SelectionInput, SelectMenu, Section, ValidationMessages };
|
|
86165
|
-
static props = {
|
|
86166
|
-
rule: { type: Object, optional: true },
|
|
86167
|
-
onExit: Function,
|
|
86168
|
-
onCloseSidePanel: { type: Function, optional: true },
|
|
86169
|
-
};
|
|
86308
|
+
static props = { ruleId: String, onCloseSidePanel: Function };
|
|
86170
86309
|
state = owl.useState({
|
|
86171
86310
|
rule: this.defaultDataValidationRule,
|
|
86172
86311
|
errors: [],
|
|
@@ -86175,12 +86314,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
86175
86314
|
editingSheetId;
|
|
86176
86315
|
setup() {
|
|
86177
86316
|
this.editingSheetId = this.env.model.getters.getActiveSheetId();
|
|
86178
|
-
|
|
86317
|
+
const rule = this.env.model.getters.getDataValidationRule(this.editingSheetId, this.props.ruleId);
|
|
86318
|
+
if (rule) {
|
|
86319
|
+
const locale = this.env.model.getters.getLocale();
|
|
86179
86320
|
this.state.rule = {
|
|
86180
|
-
...
|
|
86181
|
-
ranges:
|
|
86321
|
+
...localizeDataValidationRule(rule, locale),
|
|
86322
|
+
ranges: rule.ranges.map((range) => this.env.model.getters.getRangeString(range, this.editingSheetId)),
|
|
86182
86323
|
};
|
|
86183
|
-
this.state.rule.criterion.type = this.props.rule.criterion.type;
|
|
86184
86324
|
}
|
|
86185
86325
|
}
|
|
86186
86326
|
onCriterionTypeChanged(type) {
|
|
@@ -86197,16 +86337,16 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
86197
86337
|
const isBlocking = ev.target.value;
|
|
86198
86338
|
this.state.rule.isBlocking = isBlocking === "true";
|
|
86199
86339
|
}
|
|
86340
|
+
onCancel() {
|
|
86341
|
+
this.env.replaceSidePanel("DataValidation", `DataValidationEditor_${this.props.ruleId}`);
|
|
86342
|
+
}
|
|
86200
86343
|
onSave() {
|
|
86201
|
-
|
|
86202
|
-
|
|
86203
|
-
|
|
86204
|
-
|
|
86205
|
-
}
|
|
86206
|
-
else {
|
|
86207
|
-
this.props.onExit();
|
|
86208
|
-
}
|
|
86344
|
+
const result = this.env.model.dispatch("ADD_DATA_VALIDATION_RULE", this.dispatchPayload);
|
|
86345
|
+
if (!result.isSuccessful) {
|
|
86346
|
+
this.state.errors = result.reasons;
|
|
86347
|
+
return;
|
|
86209
86348
|
}
|
|
86349
|
+
this.env.replaceSidePanel("DataValidation", `DataValidationEditor_${this.props.ruleId}`);
|
|
86210
86350
|
}
|
|
86211
86351
|
get dispatchPayload() {
|
|
86212
86352
|
const rule = { ...this.state.rule, ranges: undefined };
|
|
@@ -86238,7 +86378,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
86238
86378
|
.getSelectedZones()
|
|
86239
86379
|
.map((zone) => zoneToXc(this.env.model.getters.getUnboundedZone(sheetId, zone)));
|
|
86240
86380
|
return {
|
|
86241
|
-
id: this.
|
|
86381
|
+
id: this.props.ruleId,
|
|
86242
86382
|
criterion: { type: "containsText", values: [""] },
|
|
86243
86383
|
ranges,
|
|
86244
86384
|
};
|
|
@@ -86251,75 +86391,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
86251
86391
|
}
|
|
86252
86392
|
}
|
|
86253
86393
|
|
|
86254
|
-
class DataValidationPreview extends owl.Component {
|
|
86255
|
-
static template = "o-spreadsheet-DataValidationPreview";
|
|
86256
|
-
static props = {
|
|
86257
|
-
onClick: Function,
|
|
86258
|
-
rule: Object,
|
|
86259
|
-
};
|
|
86260
|
-
ref = owl.useRef("dvPreview");
|
|
86261
|
-
setup() {
|
|
86262
|
-
useHighlightsOnHover(this.ref, this);
|
|
86263
|
-
}
|
|
86264
|
-
deleteDataValidation() {
|
|
86265
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
86266
|
-
this.env.model.dispatch("REMOVE_DATA_VALIDATION_RULE", { sheetId, id: this.props.rule.id });
|
|
86267
|
-
}
|
|
86268
|
-
get highlights() {
|
|
86269
|
-
return this.props.rule.ranges.map((range) => ({
|
|
86270
|
-
range,
|
|
86271
|
-
color: HIGHLIGHT_COLOR,
|
|
86272
|
-
fillAlpha: 0.06,
|
|
86273
|
-
}));
|
|
86274
|
-
}
|
|
86275
|
-
get rangesString() {
|
|
86276
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
86277
|
-
return this.props.rule.ranges
|
|
86278
|
-
.map((range) => this.env.model.getters.getRangeString(range, sheetId))
|
|
86279
|
-
.join(", ");
|
|
86280
|
-
}
|
|
86281
|
-
get descriptionString() {
|
|
86282
|
-
return criterionEvaluatorRegistry
|
|
86283
|
-
.get(this.props.rule.criterion.type)
|
|
86284
|
-
.getPreview(this.props.rule.criterion, this.env.model.getters);
|
|
86285
|
-
}
|
|
86286
|
-
}
|
|
86287
|
-
|
|
86288
|
-
class DataValidationPanel extends owl.Component {
|
|
86289
|
-
static template = "o-spreadsheet-DataValidationPanel";
|
|
86290
|
-
static props = {
|
|
86291
|
-
onCloseSidePanel: Function,
|
|
86292
|
-
};
|
|
86293
|
-
static components = { DataValidationPreview, DataValidationEditor };
|
|
86294
|
-
state = owl.useState({ mode: "list", activeRule: undefined });
|
|
86295
|
-
onPreviewClick(id) {
|
|
86296
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
86297
|
-
const rule = this.env.model.getters.getDataValidationRule(sheetId, id);
|
|
86298
|
-
if (rule) {
|
|
86299
|
-
this.state.mode = "edit";
|
|
86300
|
-
this.state.activeRule = rule;
|
|
86301
|
-
}
|
|
86302
|
-
}
|
|
86303
|
-
addDataValidationRule() {
|
|
86304
|
-
this.state.mode = "edit";
|
|
86305
|
-
this.state.activeRule = undefined;
|
|
86306
|
-
}
|
|
86307
|
-
onExitEditMode() {
|
|
86308
|
-
this.state.mode = "list";
|
|
86309
|
-
this.state.activeRule = undefined;
|
|
86310
|
-
}
|
|
86311
|
-
localizeDVRule(rule) {
|
|
86312
|
-
if (!rule)
|
|
86313
|
-
return rule;
|
|
86314
|
-
const locale = this.env.model.getters.getLocale();
|
|
86315
|
-
return localizeDataValidationRule(rule, locale);
|
|
86316
|
-
}
|
|
86317
|
-
get validationRules() {
|
|
86318
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
86319
|
-
return this.env.model.getters.getDataValidationRules(sheetId);
|
|
86320
|
-
}
|
|
86321
|
-
}
|
|
86322
|
-
|
|
86323
86394
|
const FIND_AND_REPLACE_HIGHLIGHT_COLOR = "#8B008B";
|
|
86324
86395
|
var Direction;
|
|
86325
86396
|
(function (Direction) {
|
|
@@ -89197,7 +89268,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
89197
89268
|
const sidePanelRegistry = new Registry$1();
|
|
89198
89269
|
sidePanelRegistry.add("ConditionalFormatting", {
|
|
89199
89270
|
title: _t("Conditional formatting"),
|
|
89200
|
-
Body:
|
|
89271
|
+
Body: ConditionalFormatPreviewList,
|
|
89272
|
+
});
|
|
89273
|
+
sidePanelRegistry.add("ConditionalFormattingEditor", {
|
|
89274
|
+
title: _t("Conditional formatting"),
|
|
89275
|
+
Body: ConditionalFormattingEditor,
|
|
89276
|
+
computeState: (getters, props) => {
|
|
89277
|
+
return {
|
|
89278
|
+
isOpen: true,
|
|
89279
|
+
props,
|
|
89280
|
+
key: `ConditionalFormattingEditor_${props.cf.id}`,
|
|
89281
|
+
};
|
|
89282
|
+
},
|
|
89201
89283
|
});
|
|
89202
89284
|
sidePanelRegistry.add("ChartPanel", {
|
|
89203
89285
|
title: _t("Chart"),
|
|
@@ -89234,6 +89316,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
89234
89316
|
sidePanelRegistry.add("DataValidationEditor", {
|
|
89235
89317
|
title: _t("Data validation"),
|
|
89236
89318
|
Body: DataValidationEditor,
|
|
89319
|
+
computeState: (getters, props) => {
|
|
89320
|
+
return {
|
|
89321
|
+
isOpen: true,
|
|
89322
|
+
props,
|
|
89323
|
+
key: `DataValidationEditor_${props.ruleId}`,
|
|
89324
|
+
};
|
|
89325
|
+
},
|
|
89237
89326
|
});
|
|
89238
89327
|
sidePanelRegistry.add("MoreFormats", {
|
|
89239
89328
|
title: _t("More formats"),
|
|
@@ -97985,9 +98074,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
97985
98074
|
exports.tokenize = tokenize;
|
|
97986
98075
|
|
|
97987
98076
|
|
|
97988
|
-
__info__.version = "19.
|
|
97989
|
-
__info__.date = "2026-01-07T16:21:
|
|
97990
|
-
__info__.hash = "
|
|
98077
|
+
__info__.version = "19.2.0-alpha.2";
|
|
98078
|
+
__info__.date = "2026-01-07T16:21:35.251Z";
|
|
98079
|
+
__info__.hash = "ac2fa3e";
|
|
97991
98080
|
|
|
97992
98081
|
|
|
97993
98082
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|