@odoo/o-spreadsheet 16.5.0-alpha.11 → 16.5.0-alpha.13
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 +436 -151
- package/dist/o-spreadsheet.d.ts +15 -8
- package/dist/o-spreadsheet.esm.js +436 -151
- package/dist/o-spreadsheet.iife.js +436 -151
- package/dist/o-spreadsheet.iife.min.js +283 -283
- 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 16.5.0-alpha.
|
|
6
|
-
* @date 2023-10-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 16.5.0-alpha.13
|
|
6
|
+
* @date 2023-10-25T10:04:45.428Z
|
|
7
|
+
* @hash 18a08b1
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { Component, useRef, onMounted, useEffect, onWillPatch, useState, onWillUpdateProps, onPatched, useComponent, useExternalListener, onWillUnmount, onWillStart, xml, useChildSubEnv, useSubEnv, markRaw } from '@odoo/owl';
|
|
@@ -2058,6 +2058,7 @@ var CommandResult;
|
|
|
2058
2058
|
CommandResult["InvalidDataValidationCriterionValue"] = "InvalidDataValidationCriterionValue";
|
|
2059
2059
|
CommandResult["InvalidNumberOfCriterionValues"] = "InvalidNumberOfCriterionValues";
|
|
2060
2060
|
CommandResult["BlockingValidationRule"] = "BlockingValidationRule";
|
|
2061
|
+
CommandResult["InvalidCopyPasteSelection"] = "InvalidCopyPasteSelection";
|
|
2061
2062
|
})(CommandResult || (CommandResult = {}));
|
|
2062
2063
|
|
|
2063
2064
|
const DEFAULT_LOCALES = [
|
|
@@ -4659,7 +4660,7 @@ class ChartJsComponent extends Component {
|
|
|
4659
4660
|
return `background-color: ${this.background}`;
|
|
4660
4661
|
}
|
|
4661
4662
|
get chartRuntime() {
|
|
4662
|
-
const runtime = this.env.model.getters.getChartRuntime(this.props.
|
|
4663
|
+
const runtime = this.env.model.getters.getChartRuntime(this.props.figure.id);
|
|
4663
4664
|
if (!("chartJsConfig" in runtime)) {
|
|
4664
4665
|
throw new Error("Unsupported chart runtime");
|
|
4665
4666
|
}
|
|
@@ -4703,7 +4704,7 @@ class ChartJsComponent extends Component {
|
|
|
4703
4704
|
}
|
|
4704
4705
|
}
|
|
4705
4706
|
ChartJsComponent.props = {
|
|
4706
|
-
|
|
4707
|
+
figure: Object,
|
|
4707
4708
|
};
|
|
4708
4709
|
|
|
4709
4710
|
/**
|
|
@@ -5105,6 +5106,8 @@ function checkBaseline(definition) {
|
|
|
5105
5106
|
? "InvalidScorecardBaseline" /* CommandResult.InvalidScorecardBaseline */
|
|
5106
5107
|
: "Success" /* CommandResult.Success */;
|
|
5107
5108
|
}
|
|
5109
|
+
const arrowDownPath = new window.Path2D("M8.6 4.8a.5.5 0 0 1 0 .75l-3.9 3.9a.5 .5 0 0 1 -.75 0l-3.8 -3.9a.5 .5 0 0 1 0 -.75l.4-.4a.5.5 0 0 1 .75 0l2.3 2.4v-5.7c0-.25.25-.5.5-.5h.6c.25 0 .5.25.5.5v5.8l2.3 -2.4a.5.5 0 0 1 .75 0z");
|
|
5110
|
+
const arrowUpPath = new window.Path2D("M8.7 5.5a.5.5 0 0 0 0-.75l-3.8-4a.5.5 0 0 0-.75 0l-3.8 4a.5.5 0 0 0 0 .75l.4.4a.5.5 0 0 0 .75 0l2.3-2.4v5.8c0 .25.25.5.5.5h.6c.25 0 .5-.25.5-.5v-5.8l2.2 2.4a.5.5 0 0 0 .75 0z");
|
|
5108
5111
|
let ScorecardChart$1 = class ScorecardChart extends AbstractChart {
|
|
5109
5112
|
keyValue;
|
|
5110
5113
|
baseline;
|
|
@@ -5225,10 +5228,24 @@ function drawScoreChart(structure, canvas) {
|
|
|
5225
5228
|
ctx.fillStyle = structure.baseline.style.color;
|
|
5226
5229
|
drawDecoratedText(ctx, structure.baseline.text, structure.baseline.position, structure.baseline.style.underline, structure.baseline.style.strikethrough);
|
|
5227
5230
|
}
|
|
5228
|
-
if (structure.baselineArrow) {
|
|
5229
|
-
ctx.
|
|
5231
|
+
if (structure.baselineArrow && structure.baselineArrow.style.size > 0) {
|
|
5232
|
+
ctx.save();
|
|
5230
5233
|
ctx.fillStyle = structure.baselineArrow.style.color;
|
|
5231
|
-
ctx.
|
|
5234
|
+
ctx.translate(structure.baselineArrow.position.x, structure.baselineArrow.position.y);
|
|
5235
|
+
// This ratio is computed according to the original svg size and the final size we want
|
|
5236
|
+
const ratio = structure.baselineArrow.style.size / 10;
|
|
5237
|
+
ctx.scale(ratio, ratio);
|
|
5238
|
+
switch (structure.baselineArrow.direction) {
|
|
5239
|
+
case "down": {
|
|
5240
|
+
ctx.fill(arrowDownPath);
|
|
5241
|
+
break;
|
|
5242
|
+
}
|
|
5243
|
+
case "up": {
|
|
5244
|
+
ctx.fill(arrowUpPath);
|
|
5245
|
+
break;
|
|
5246
|
+
}
|
|
5247
|
+
}
|
|
5248
|
+
ctx.restore();
|
|
5232
5249
|
}
|
|
5233
5250
|
if (structure.baselineDescr) {
|
|
5234
5251
|
ctx.font = structure.baselineDescr.style.font;
|
|
@@ -5351,25 +5368,29 @@ class ScorecardChartConfigBuilder {
|
|
|
5351
5368
|
},
|
|
5352
5369
|
};
|
|
5353
5370
|
}
|
|
5354
|
-
const
|
|
5371
|
+
const baselineArrowSize = style.baselineArrow?.size ?? 0;
|
|
5355
5372
|
const { height: baselineHeight, width: baselineWidth } = this.getTextDimensions(this.baseline, style.baselineValue.font);
|
|
5356
5373
|
const { width: baselineDescrWidth } = this.getTextDimensions(this.baselineDescr, style.baselineDescr.font);
|
|
5357
5374
|
structure.baseline = {
|
|
5358
5375
|
text: this.baseline,
|
|
5359
5376
|
style: style.baselineValue,
|
|
5360
5377
|
position: {
|
|
5361
|
-
x: (this.width - baselineWidth - baselineDescrWidth +
|
|
5362
|
-
y: this.
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
structure.baselineArrow = {
|
|
5366
|
-
text: this.baselineArrow,
|
|
5367
|
-
style: style.baselineArrow,
|
|
5368
|
-
position: {
|
|
5369
|
-
x: structure.baseline.position.x - baselineArrowWidth,
|
|
5370
|
-
y: structure.baseline.position.y - (baselineHeight - baselineArrowHeight) / 2,
|
|
5378
|
+
x: (this.width - baselineWidth - baselineDescrWidth + baselineArrowSize) / 2,
|
|
5379
|
+
y: this.keyValue
|
|
5380
|
+
? this.height - 2 * this.chartPadding
|
|
5381
|
+
: this.height - (this.height - titleHeight - baselineHeight) / 2 - this.chartPadding,
|
|
5371
5382
|
},
|
|
5372
5383
|
};
|
|
5384
|
+
if (style.baselineArrow) {
|
|
5385
|
+
structure.baselineArrow = {
|
|
5386
|
+
direction: this.baselineArrow,
|
|
5387
|
+
style: style.baselineArrow,
|
|
5388
|
+
position: {
|
|
5389
|
+
x: structure.baseline.position.x - baselineArrowSize,
|
|
5390
|
+
y: structure.baseline.position.y - (baselineHeight + baselineArrowSize) / 2,
|
|
5391
|
+
},
|
|
5392
|
+
};
|
|
5393
|
+
}
|
|
5373
5394
|
if (this.baselineDescr) {
|
|
5374
5395
|
structure.baselineDescr = {
|
|
5375
5396
|
text: this.baselineDescr,
|
|
@@ -5406,13 +5427,7 @@ class ScorecardChartConfigBuilder {
|
|
|
5406
5427
|
return formatBaselineDescr(this.runtime.baselineDescr, this.baseline);
|
|
5407
5428
|
}
|
|
5408
5429
|
get baselineArrow() {
|
|
5409
|
-
|
|
5410
|
-
case "up":
|
|
5411
|
-
return "\u{1F871}";
|
|
5412
|
-
case "down":
|
|
5413
|
-
return "\u{1F873}";
|
|
5414
|
-
}
|
|
5415
|
-
return "";
|
|
5430
|
+
return this.runtime.baselineArrow;
|
|
5416
5431
|
}
|
|
5417
5432
|
get backgroundColor() {
|
|
5418
5433
|
return this.runtime.background;
|
|
@@ -5464,10 +5479,12 @@ class ScorecardChartConfigBuilder {
|
|
|
5464
5479
|
font: getDefaultContextFont(baselineFontSize * BASELINE_DESCR_FONT_RATIO),
|
|
5465
5480
|
color: this.secondaryFontColor,
|
|
5466
5481
|
},
|
|
5467
|
-
baselineArrow:
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5482
|
+
baselineArrow: this.baselineArrow === "neutral"
|
|
5483
|
+
? undefined
|
|
5484
|
+
: {
|
|
5485
|
+
size: this.keyValue ? 0.8 * baselineFontSize : 0,
|
|
5486
|
+
color: this.runtime.baselineColor || this.secondaryFontColor,
|
|
5487
|
+
},
|
|
5471
5488
|
};
|
|
5472
5489
|
}
|
|
5473
5490
|
/** Get the height of the chart minus all the vertical paddings */
|
|
@@ -5504,7 +5521,7 @@ class BaselineElement extends ScorecardScalableElement {
|
|
|
5504
5521
|
}
|
|
5505
5522
|
const baselineStr = chart.baseline;
|
|
5506
5523
|
// Put mock text to simulate the width of the up/down arrow
|
|
5507
|
-
const largeText = chart.baselineArrow !== "" ? "A " + baselineStr : baselineStr;
|
|
5524
|
+
const largeText = chart.baselineArrow !== "neutral" ? "A " + baselineStr : baselineStr;
|
|
5508
5525
|
let textWidth = this.measureTextWidth(ctx, largeText, fontSize);
|
|
5509
5526
|
// Baseline descr font size should be smaller than baseline font size
|
|
5510
5527
|
textWidth += this.measureTextWidth(ctx, chart.baselineDescr, fontSize * BASELINE_DESCR_FONT_RATIO);
|
|
@@ -5541,7 +5558,7 @@ class ScorecardChart extends Component {
|
|
|
5541
5558
|
static template = "o-spreadsheet-ScorecardChart";
|
|
5542
5559
|
canvas = useRef("chartContainer");
|
|
5543
5560
|
get runtime() {
|
|
5544
|
-
return this.env.model.getters.getChartRuntime(this.props.
|
|
5561
|
+
return this.env.model.getters.getChartRuntime(this.props.figure.id);
|
|
5545
5562
|
}
|
|
5546
5563
|
setup() {
|
|
5547
5564
|
useEffect(this.createChart.bind(this), () => {
|
|
@@ -5557,7 +5574,7 @@ class ScorecardChart extends Component {
|
|
|
5557
5574
|
}
|
|
5558
5575
|
}
|
|
5559
5576
|
ScorecardChart.props = {
|
|
5560
|
-
|
|
5577
|
+
figure: Object,
|
|
5561
5578
|
};
|
|
5562
5579
|
|
|
5563
5580
|
/**
|
|
@@ -7566,6 +7583,18 @@ function multiplyMatrices(matrix1, matrix2) {
|
|
|
7566
7583
|
}
|
|
7567
7584
|
return result;
|
|
7568
7585
|
}
|
|
7586
|
+
/**
|
|
7587
|
+
* Return the input if it's a scalar or the first element of the input if it's a matrix.
|
|
7588
|
+
*/
|
|
7589
|
+
function toScalar(matrix) {
|
|
7590
|
+
if (!isMatrix(matrix)) {
|
|
7591
|
+
return matrix;
|
|
7592
|
+
}
|
|
7593
|
+
if (matrix.length !== 1 || matrix[0].length !== 1) {
|
|
7594
|
+
throw new Error("toScalar: matrix should be a scalar or a 1x1 matrix");
|
|
7595
|
+
}
|
|
7596
|
+
return matrix[0][0];
|
|
7597
|
+
}
|
|
7569
7598
|
|
|
7570
7599
|
// -----------------------------------------------------------------------------
|
|
7571
7600
|
// ARRAY_CONSTRAIN
|
|
@@ -10279,6 +10308,42 @@ const QUARTILE_INC = {
|
|
|
10279
10308
|
},
|
|
10280
10309
|
isExported: true,
|
|
10281
10310
|
};
|
|
10311
|
+
// RANK
|
|
10312
|
+
// -----------------------------------------------------------------------------
|
|
10313
|
+
const RANK = {
|
|
10314
|
+
description: _t("Returns the rank of a specified value in a dataset."),
|
|
10315
|
+
args: [
|
|
10316
|
+
arg("value (number)", _t("The value whose rank will be determined.")),
|
|
10317
|
+
arg("data (range)", _t("The range containing the dataset to consider.")),
|
|
10318
|
+
arg("is_ascending (boolean, default=FALSE)", _t("Whether to consider the values in data in descending or ascending order.")),
|
|
10319
|
+
],
|
|
10320
|
+
returns: ["ANY"],
|
|
10321
|
+
compute: function (value, data, isAscending = false) {
|
|
10322
|
+
const _isAscending = toBoolean(isAscending);
|
|
10323
|
+
const _value = toNumber(value, this.locale);
|
|
10324
|
+
let rank = 1;
|
|
10325
|
+
let found = false;
|
|
10326
|
+
for (const row of data) {
|
|
10327
|
+
for (const cell of row) {
|
|
10328
|
+
if (typeof cell !== "number") {
|
|
10329
|
+
continue;
|
|
10330
|
+
}
|
|
10331
|
+
const _cell = toNumber(cell, this.locale);
|
|
10332
|
+
if (_cell === _value) {
|
|
10333
|
+
found = true;
|
|
10334
|
+
}
|
|
10335
|
+
else if (_cell > _value !== _isAscending) {
|
|
10336
|
+
rank++;
|
|
10337
|
+
}
|
|
10338
|
+
}
|
|
10339
|
+
}
|
|
10340
|
+
if (!found) {
|
|
10341
|
+
throw new NotAvailableError(_t("Value not found in the given data."));
|
|
10342
|
+
}
|
|
10343
|
+
return rank;
|
|
10344
|
+
},
|
|
10345
|
+
isExported: true,
|
|
10346
|
+
};
|
|
10282
10347
|
// -----------------------------------------------------------------------------
|
|
10283
10348
|
// RSQ
|
|
10284
10349
|
// -----------------------------------------------------------------------------
|
|
@@ -10623,6 +10688,7 @@ var statistical = /*#__PURE__*/Object.freeze({
|
|
|
10623
10688
|
QUARTILE: QUARTILE,
|
|
10624
10689
|
QUARTILE_EXC: QUARTILE_EXC,
|
|
10625
10690
|
QUARTILE_INC: QUARTILE_INC,
|
|
10691
|
+
RANK: RANK,
|
|
10626
10692
|
RSQ: RSQ,
|
|
10627
10693
|
SLOPE: SLOPE,
|
|
10628
10694
|
SMALL: SMALL,
|
|
@@ -11769,6 +11835,172 @@ var engineering = /*#__PURE__*/Object.freeze({
|
|
|
11769
11835
|
DELTA: DELTA
|
|
11770
11836
|
});
|
|
11771
11837
|
|
|
11838
|
+
const SORT_TYPES = [
|
|
11839
|
+
CellValueType.number,
|
|
11840
|
+
CellValueType.error,
|
|
11841
|
+
CellValueType.text,
|
|
11842
|
+
CellValueType.boolean,
|
|
11843
|
+
];
|
|
11844
|
+
function cellsSortingCriterion(sortingOrder) {
|
|
11845
|
+
const inverse = sortingOrder === "ascending" ? 1 : -1;
|
|
11846
|
+
return (left, right) => {
|
|
11847
|
+
if (left.type === CellValueType.empty) {
|
|
11848
|
+
return right.type === CellValueType.empty ? 0 : 1;
|
|
11849
|
+
}
|
|
11850
|
+
else if (right.type === CellValueType.empty) {
|
|
11851
|
+
return -1;
|
|
11852
|
+
}
|
|
11853
|
+
let typeOrder = SORT_TYPES.indexOf(left.type) - SORT_TYPES.indexOf(right.type);
|
|
11854
|
+
if (typeOrder === 0) {
|
|
11855
|
+
if (left.type === CellValueType.text || left.type === CellValueType.error) {
|
|
11856
|
+
typeOrder = left.value.localeCompare(right.value);
|
|
11857
|
+
}
|
|
11858
|
+
else {
|
|
11859
|
+
typeOrder = left.value - right.value;
|
|
11860
|
+
}
|
|
11861
|
+
}
|
|
11862
|
+
return inverse * typeOrder;
|
|
11863
|
+
};
|
|
11864
|
+
}
|
|
11865
|
+
function sortCells(cells, sortDirection, emptyCellAsZero) {
|
|
11866
|
+
const cellsWithIndex = cells.map((cell, index) => ({
|
|
11867
|
+
index,
|
|
11868
|
+
type: cell.type,
|
|
11869
|
+
value: cell.value,
|
|
11870
|
+
}));
|
|
11871
|
+
const cellsToSort = emptyCellAsZero
|
|
11872
|
+
? cellsWithIndex.map((cell) => cell.type === CellValueType.empty ? { ...cell, type: CellValueType.number, value: 0 } : cell)
|
|
11873
|
+
: cellsWithIndex;
|
|
11874
|
+
return cellsToSort.sort(cellsSortingCriterion(sortDirection));
|
|
11875
|
+
}
|
|
11876
|
+
function interactiveSortSelection(env, sheetId, anchor, zone, sortDirection) {
|
|
11877
|
+
let result = DispatchResult.Success;
|
|
11878
|
+
//several columns => bypass the contiguity check
|
|
11879
|
+
let multiColumns = zone.right > zone.left;
|
|
11880
|
+
if (env.model.getters.doesIntersectMerge(sheetId, zone)) {
|
|
11881
|
+
multiColumns = false;
|
|
11882
|
+
let table;
|
|
11883
|
+
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
11884
|
+
table = [];
|
|
11885
|
+
for (let col = zone.left; col <= zone.right; col++) {
|
|
11886
|
+
let merge = env.model.getters.getMerge({ sheetId, col, row });
|
|
11887
|
+
if (merge && !table.includes(merge.id.toString())) {
|
|
11888
|
+
table.push(merge.id.toString());
|
|
11889
|
+
}
|
|
11890
|
+
}
|
|
11891
|
+
if (table.length >= 2) {
|
|
11892
|
+
multiColumns = true;
|
|
11893
|
+
break;
|
|
11894
|
+
}
|
|
11895
|
+
}
|
|
11896
|
+
}
|
|
11897
|
+
const { col, row } = anchor;
|
|
11898
|
+
if (multiColumns) {
|
|
11899
|
+
result = env.model.dispatch("SORT_CELLS", { sheetId, col, row, zone, sortDirection });
|
|
11900
|
+
}
|
|
11901
|
+
else {
|
|
11902
|
+
// check contiguity
|
|
11903
|
+
const contiguousZone = env.model.getters.getContiguousZone(sheetId, zone);
|
|
11904
|
+
if (isEqual(contiguousZone, zone)) {
|
|
11905
|
+
// merge as it is
|
|
11906
|
+
result = env.model.dispatch("SORT_CELLS", {
|
|
11907
|
+
sheetId,
|
|
11908
|
+
col,
|
|
11909
|
+
row,
|
|
11910
|
+
zone,
|
|
11911
|
+
sortDirection,
|
|
11912
|
+
});
|
|
11913
|
+
}
|
|
11914
|
+
else {
|
|
11915
|
+
env.askConfirmation(_t("We found data next to your selection. Since this data was not selected, it will not be sorted. Do you want to extend your selection?"), () => {
|
|
11916
|
+
zone = contiguousZone;
|
|
11917
|
+
result = env.model.dispatch("SORT_CELLS", {
|
|
11918
|
+
sheetId,
|
|
11919
|
+
col,
|
|
11920
|
+
row,
|
|
11921
|
+
zone,
|
|
11922
|
+
sortDirection,
|
|
11923
|
+
});
|
|
11924
|
+
}, () => {
|
|
11925
|
+
result = env.model.dispatch("SORT_CELLS", {
|
|
11926
|
+
sheetId,
|
|
11927
|
+
col,
|
|
11928
|
+
row,
|
|
11929
|
+
zone,
|
|
11930
|
+
sortDirection,
|
|
11931
|
+
});
|
|
11932
|
+
});
|
|
11933
|
+
}
|
|
11934
|
+
}
|
|
11935
|
+
if (result.isCancelledBecause("InvalidSortZone" /* CommandResult.InvalidSortZone */)) {
|
|
11936
|
+
const { col, row } = anchor;
|
|
11937
|
+
env.model.selection.selectZone({ cell: { col, row }, zone });
|
|
11938
|
+
env.raiseError(_t("Cannot sort. To sort, select only cells or only merges that have the same size."));
|
|
11939
|
+
}
|
|
11940
|
+
}
|
|
11941
|
+
|
|
11942
|
+
function sortMatrix(matrix, locale, ...criteria) {
|
|
11943
|
+
for (const [i, value] of criteria.entries()) {
|
|
11944
|
+
assert(() => value !== undefined, _t(`Value for parameter %d is missing, while the function [[FUNCTION_NAME]] expect a number or a range.`, i + 1));
|
|
11945
|
+
}
|
|
11946
|
+
const sortingOrders = [];
|
|
11947
|
+
const sortColumns = [];
|
|
11948
|
+
const nRows = matrix.length;
|
|
11949
|
+
for (let i = 0; i < criteria.length; i += 2) {
|
|
11950
|
+
sortingOrders.push(toBoolean(toScalar(criteria[i + 1])?.value) ? "ascending" : "descending");
|
|
11951
|
+
const sortColumn = criteria[i];
|
|
11952
|
+
if (isMatrix(sortColumn) && (sortColumn.length > 1 || sortColumn[0].length > 1)) {
|
|
11953
|
+
assert(() => sortColumn.length === 1 && sortColumn[0].length === nRows, _t(`Wrong size for %s. Expected a range of size 1x%s. Got %sx%s.`, `sort_column{i + 1}`, nRows, sortColumn.length, sortColumn[0].length));
|
|
11954
|
+
sortColumns.push(sortColumn.flat().map((c) => c.value));
|
|
11955
|
+
}
|
|
11956
|
+
else {
|
|
11957
|
+
const colIndex = toNumber(toScalar(sortColumn)?.value, locale);
|
|
11958
|
+
if (colIndex < 1 || colIndex > matrix[0].length) {
|
|
11959
|
+
return matrix;
|
|
11960
|
+
}
|
|
11961
|
+
sortColumns.push(matrix.map((row) => row[colIndex - 1].value));
|
|
11962
|
+
}
|
|
11963
|
+
}
|
|
11964
|
+
if (sortColumns.length === 0) {
|
|
11965
|
+
for (let i = 0; i < matrix[0].length; i++) {
|
|
11966
|
+
sortColumns.push(matrix.map((row) => row[i].value));
|
|
11967
|
+
sortingOrders.push("ascending");
|
|
11968
|
+
}
|
|
11969
|
+
}
|
|
11970
|
+
const sortingCriteria = {
|
|
11971
|
+
descending: cellsSortingCriterion("descending"),
|
|
11972
|
+
ascending: cellsSortingCriterion("ascending"),
|
|
11973
|
+
};
|
|
11974
|
+
const indexes = range(0, matrix.length);
|
|
11975
|
+
indexes.sort((a, b) => {
|
|
11976
|
+
for (const [i, sortColumn] of sortColumns.entries()) {
|
|
11977
|
+
const left = sortColumn[a];
|
|
11978
|
+
const right = sortColumn[b];
|
|
11979
|
+
const leftCell = {
|
|
11980
|
+
value: left,
|
|
11981
|
+
type: left === null
|
|
11982
|
+
? CellValueType.empty
|
|
11983
|
+
: typeof left === "string"
|
|
11984
|
+
? CellValueType.text
|
|
11985
|
+
: typeof left,
|
|
11986
|
+
};
|
|
11987
|
+
const rightCell = {
|
|
11988
|
+
value: right,
|
|
11989
|
+
type: right === null
|
|
11990
|
+
? CellValueType.empty
|
|
11991
|
+
: typeof right === "string"
|
|
11992
|
+
? CellValueType.text
|
|
11993
|
+
: typeof right,
|
|
11994
|
+
};
|
|
11995
|
+
const result = sortingCriteria[sortingOrders[i]](leftCell, rightCell);
|
|
11996
|
+
if (result !== 0) {
|
|
11997
|
+
return result;
|
|
11998
|
+
}
|
|
11999
|
+
}
|
|
12000
|
+
return 0;
|
|
12001
|
+
});
|
|
12002
|
+
return indexes.map((i) => matrix[i]);
|
|
12003
|
+
}
|
|
11772
12004
|
// -----------------------------------------------------------------------------
|
|
11773
12005
|
// FILTER
|
|
11774
12006
|
// -----------------------------------------------------------------------------
|
|
@@ -11805,6 +12037,93 @@ const FILTER = {
|
|
|
11805
12037
|
isExported: true,
|
|
11806
12038
|
};
|
|
11807
12039
|
// -----------------------------------------------------------------------------
|
|
12040
|
+
// SORT
|
|
12041
|
+
// -----------------------------------------------------------------------------
|
|
12042
|
+
const SORT = {
|
|
12043
|
+
description: _t("Sorts the rows of a given array or range by the values in one or more columns."),
|
|
12044
|
+
args: [
|
|
12045
|
+
arg("range (range)", _t("The data to be sorted.")),
|
|
12046
|
+
arg("sort_column (any, range<number>, repeating)", _t("The index of the column in range or a range outside of range containing the values by which to sort.")),
|
|
12047
|
+
arg("is_ascending (boolean, repeating)", _t("TRUE or FALSE indicating whether to sort sort_column in ascending order. FALSE sorts in descending order.")),
|
|
12048
|
+
],
|
|
12049
|
+
returns: ["RANGE"],
|
|
12050
|
+
computeValueAndFormat: function (range, ...sortingCriteria) {
|
|
12051
|
+
const _range = transposeMatrix(range);
|
|
12052
|
+
return transposeMatrix(sortMatrix(_range, this.locale, ...sortingCriteria));
|
|
12053
|
+
},
|
|
12054
|
+
isExported: true,
|
|
12055
|
+
};
|
|
12056
|
+
// -----------------------------------------------------------------------------
|
|
12057
|
+
// SORTN
|
|
12058
|
+
// -----------------------------------------------------------------------------
|
|
12059
|
+
const SORTN = {
|
|
12060
|
+
description: _t("Returns the first n items in a data set after performing a sort."),
|
|
12061
|
+
args: [
|
|
12062
|
+
arg("range (range)", _t("The data to be sorted.")),
|
|
12063
|
+
arg("n (number, default=1)", _t("The number of items to return.")),
|
|
12064
|
+
arg("display_ties_mode (number, default=0)", _t("A number representing the way to display ties.")),
|
|
12065
|
+
arg("sort_column (number, range<number>, repeating)", _t("The index of the column in range or a range outside of range containing the values by which to sort.")),
|
|
12066
|
+
arg("is_ascending (boolean, repeating)", _t("TRUE or FALSE indicating whether to sort sort_column in ascending order. FALSE sorts in descending order.")),
|
|
12067
|
+
],
|
|
12068
|
+
returns: ["RANGE"],
|
|
12069
|
+
computeValueAndFormat: function (range, n, displayTiesMode, ...sortingCriteria) {
|
|
12070
|
+
const _n = toNumber(n?.value ?? 1, this.locale);
|
|
12071
|
+
assert(() => _n >= 0, _t(`Wrong value of 'n'. Expected a positive number. Got %s.`, _n));
|
|
12072
|
+
const _displayTiesMode = toNumber(displayTiesMode?.value ?? 0, this.locale);
|
|
12073
|
+
assert(() => _displayTiesMode >= 0 && _displayTiesMode <= 3, _t(`Wrong value of 'display_ties_mode'. Expected a positive number between 0 and 3. Got %s.`, _displayTiesMode));
|
|
12074
|
+
const sortedData = sortMatrix(transposeMatrix(range), this.locale, ...sortingCriteria);
|
|
12075
|
+
const sameRows = (i, j) => JSON.stringify(sortedData[i].map((c) => c.value)) ===
|
|
12076
|
+
JSON.stringify(sortedData[j].map((c) => c.value));
|
|
12077
|
+
/*
|
|
12078
|
+
* displayTiesMode determine how ties (equal values) are dealt with:
|
|
12079
|
+
* 0 - ignore ties and show first n rows only
|
|
12080
|
+
* 1 - show first n rows plus any additional ties with nth row
|
|
12081
|
+
* 2 - show n rows but remove duplicates
|
|
12082
|
+
* 3 - show first n unique rows and all duplicates of these rows
|
|
12083
|
+
*/
|
|
12084
|
+
switch (_displayTiesMode) {
|
|
12085
|
+
case 0:
|
|
12086
|
+
return transposeMatrix(sortedData.slice(0, _n));
|
|
12087
|
+
case 1:
|
|
12088
|
+
for (let i = _n; i < sortedData.length; i++) {
|
|
12089
|
+
if (!sameRows(i, _n - 1)) {
|
|
12090
|
+
return transposeMatrix(sortedData.slice(0, i));
|
|
12091
|
+
}
|
|
12092
|
+
}
|
|
12093
|
+
return transposeMatrix(sortedData);
|
|
12094
|
+
case 2: {
|
|
12095
|
+
const uniques = [sortedData[0]];
|
|
12096
|
+
for (let i = 1; i < sortedData.length; i++) {
|
|
12097
|
+
for (let j = 0; j < i; j++) {
|
|
12098
|
+
if (sameRows(i, j)) {
|
|
12099
|
+
break;
|
|
12100
|
+
}
|
|
12101
|
+
if (j === i - 1) {
|
|
12102
|
+
uniques.push(sortedData[i]);
|
|
12103
|
+
}
|
|
12104
|
+
}
|
|
12105
|
+
}
|
|
12106
|
+
return transposeMatrix(uniques.slice(0, _n));
|
|
12107
|
+
}
|
|
12108
|
+
case 3: {
|
|
12109
|
+
const uniques = [sortedData[0]];
|
|
12110
|
+
let counter = 1;
|
|
12111
|
+
for (let i = 1; i < sortedData.length; i++) {
|
|
12112
|
+
if (!sameRows(i, i - 1)) {
|
|
12113
|
+
counter++;
|
|
12114
|
+
}
|
|
12115
|
+
if (counter > _n) {
|
|
12116
|
+
break;
|
|
12117
|
+
}
|
|
12118
|
+
uniques.push(sortedData[i]);
|
|
12119
|
+
}
|
|
12120
|
+
return transposeMatrix(uniques);
|
|
12121
|
+
}
|
|
12122
|
+
}
|
|
12123
|
+
},
|
|
12124
|
+
isExported: true,
|
|
12125
|
+
};
|
|
12126
|
+
// -----------------------------------------------------------------------------
|
|
11808
12127
|
// UNIQUE
|
|
11809
12128
|
// -----------------------------------------------------------------------------
|
|
11810
12129
|
const UNIQUE = {
|
|
@@ -11852,6 +12171,8 @@ const UNIQUE = {
|
|
|
11852
12171
|
var filter = /*#__PURE__*/Object.freeze({
|
|
11853
12172
|
__proto__: null,
|
|
11854
12173
|
FILTER: FILTER,
|
|
12174
|
+
SORT: SORT,
|
|
12175
|
+
SORTN: SORTN,
|
|
11855
12176
|
UNIQUE: UNIQUE
|
|
11856
12177
|
});
|
|
11857
12178
|
|
|
@@ -17087,7 +17408,7 @@ const PasteInteractiveContent = {
|
|
|
17087
17408
|
wrongPasteSelection: _t("This operation is not allowed with multiple selections."),
|
|
17088
17409
|
willRemoveExistingMerge: _t("This operation is not possible due to a merge. Please remove the merges first than try again."),
|
|
17089
17410
|
wrongFigurePasteOption: _t("Cannot do a special paste of a figure."),
|
|
17090
|
-
frozenPaneOverlap: _t("
|
|
17411
|
+
frozenPaneOverlap: _t("This operation is not allowed due to an overlapping frozen pane."),
|
|
17091
17412
|
};
|
|
17092
17413
|
function handlePasteResult(env, result) {
|
|
17093
17414
|
if (!result.isSuccessful) {
|
|
@@ -18627,11 +18948,11 @@ class ChartFigure extends Component {
|
|
|
18627
18948
|
static template = "o-spreadsheet-ChartFigure";
|
|
18628
18949
|
static components = {};
|
|
18629
18950
|
onDoubleClick() {
|
|
18630
|
-
this.env.model.dispatch("SELECT_FIGURE", { id: this.props.
|
|
18951
|
+
this.env.model.dispatch("SELECT_FIGURE", { id: this.props.figure.id });
|
|
18631
18952
|
this.env.openSidePanel("ChartPanel");
|
|
18632
18953
|
}
|
|
18633
18954
|
get chartType() {
|
|
18634
|
-
return this.env.model.getters.getChartType(this.props.
|
|
18955
|
+
return this.env.model.getters.getChartType(this.props.figure.id);
|
|
18635
18956
|
}
|
|
18636
18957
|
get chartComponent() {
|
|
18637
18958
|
const type = this.chartType;
|
|
@@ -18643,7 +18964,7 @@ class ChartFigure extends Component {
|
|
|
18643
18964
|
}
|
|
18644
18965
|
}
|
|
18645
18966
|
ChartFigure.props = {
|
|
18646
|
-
|
|
18967
|
+
figure: Object,
|
|
18647
18968
|
onFigureDeleted: Function,
|
|
18648
18969
|
};
|
|
18649
18970
|
|
|
@@ -18654,14 +18975,14 @@ class ImageFigure extends Component {
|
|
|
18654
18975
|
// Getters
|
|
18655
18976
|
// ---------------------------------------------------------------------------
|
|
18656
18977
|
get figureId() {
|
|
18657
|
-
return this.props.
|
|
18978
|
+
return this.props.figure.id;
|
|
18658
18979
|
}
|
|
18659
18980
|
get getImagePath() {
|
|
18660
18981
|
return this.env.model.getters.getImagePath(this.figureId);
|
|
18661
18982
|
}
|
|
18662
18983
|
}
|
|
18663
18984
|
ImageFigure.props = {
|
|
18664
|
-
|
|
18985
|
+
figure: Object,
|
|
18665
18986
|
onFigureDeleted: Function,
|
|
18666
18987
|
};
|
|
18667
18988
|
|
|
@@ -20266,105 +20587,6 @@ cellMenuRegistry
|
|
|
20266
20587
|
separator: true,
|
|
20267
20588
|
});
|
|
20268
20589
|
|
|
20269
|
-
const SORT_TYPES = [
|
|
20270
|
-
CellValueType.number,
|
|
20271
|
-
CellValueType.error,
|
|
20272
|
-
CellValueType.text,
|
|
20273
|
-
CellValueType.boolean,
|
|
20274
|
-
];
|
|
20275
|
-
function sortCells(cells, sortDirection, emptyCellAsZero) {
|
|
20276
|
-
const cellsWithIndex = cells.map((cell, index) => ({
|
|
20277
|
-
index,
|
|
20278
|
-
type: cell.type,
|
|
20279
|
-
value: cell.value,
|
|
20280
|
-
}));
|
|
20281
|
-
let emptyCells = cellsWithIndex.filter((x) => x.type === CellValueType.empty);
|
|
20282
|
-
let nonEmptyCells = cellsWithIndex.filter((x) => x.type !== CellValueType.empty);
|
|
20283
|
-
if (emptyCellAsZero) {
|
|
20284
|
-
nonEmptyCells.push(...emptyCells.map((emptyCell) => ({ ...emptyCell, type: CellValueType.number, value: 0 })));
|
|
20285
|
-
emptyCells = [];
|
|
20286
|
-
}
|
|
20287
|
-
const inverse = sortDirection === "descending" ? -1 : 1;
|
|
20288
|
-
return nonEmptyCells
|
|
20289
|
-
.sort((left, right) => {
|
|
20290
|
-
let typeOrder = SORT_TYPES.indexOf(left.type) - SORT_TYPES.indexOf(right.type);
|
|
20291
|
-
if (typeOrder === 0) {
|
|
20292
|
-
if (left.type === CellValueType.text || left.type === CellValueType.error) {
|
|
20293
|
-
typeOrder = left.value.localeCompare(right.value);
|
|
20294
|
-
}
|
|
20295
|
-
else
|
|
20296
|
-
typeOrder = left.value - right.value;
|
|
20297
|
-
}
|
|
20298
|
-
return inverse * typeOrder;
|
|
20299
|
-
})
|
|
20300
|
-
.concat(emptyCells);
|
|
20301
|
-
}
|
|
20302
|
-
function interactiveSortSelection(env, sheetId, anchor, zone, sortDirection) {
|
|
20303
|
-
let result = DispatchResult.Success;
|
|
20304
|
-
//several columns => bypass the contiguity check
|
|
20305
|
-
let multiColumns = zone.right > zone.left;
|
|
20306
|
-
if (env.model.getters.doesIntersectMerge(sheetId, zone)) {
|
|
20307
|
-
multiColumns = false;
|
|
20308
|
-
let table;
|
|
20309
|
-
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
20310
|
-
table = [];
|
|
20311
|
-
for (let col = zone.left; col <= zone.right; col++) {
|
|
20312
|
-
let merge = env.model.getters.getMerge({ sheetId, col, row });
|
|
20313
|
-
if (merge && !table.includes(merge.id.toString())) {
|
|
20314
|
-
table.push(merge.id.toString());
|
|
20315
|
-
}
|
|
20316
|
-
}
|
|
20317
|
-
if (table.length >= 2) {
|
|
20318
|
-
multiColumns = true;
|
|
20319
|
-
break;
|
|
20320
|
-
}
|
|
20321
|
-
}
|
|
20322
|
-
}
|
|
20323
|
-
const { col, row } = anchor;
|
|
20324
|
-
if (multiColumns) {
|
|
20325
|
-
result = env.model.dispatch("SORT_CELLS", { sheetId, col, row, zone, sortDirection });
|
|
20326
|
-
}
|
|
20327
|
-
else {
|
|
20328
|
-
// check contiguity
|
|
20329
|
-
const contiguousZone = env.model.getters.getContiguousZone(sheetId, zone);
|
|
20330
|
-
if (isEqual(contiguousZone, zone)) {
|
|
20331
|
-
// merge as it is
|
|
20332
|
-
result = env.model.dispatch("SORT_CELLS", {
|
|
20333
|
-
sheetId,
|
|
20334
|
-
col,
|
|
20335
|
-
row,
|
|
20336
|
-
zone,
|
|
20337
|
-
sortDirection,
|
|
20338
|
-
});
|
|
20339
|
-
}
|
|
20340
|
-
else {
|
|
20341
|
-
env.askConfirmation(_t("We found data next to your selection. Since this data was not selected, it will not be sorted. Do you want to extend your selection?"), () => {
|
|
20342
|
-
zone = contiguousZone;
|
|
20343
|
-
result = env.model.dispatch("SORT_CELLS", {
|
|
20344
|
-
sheetId,
|
|
20345
|
-
col,
|
|
20346
|
-
row,
|
|
20347
|
-
zone,
|
|
20348
|
-
sortDirection,
|
|
20349
|
-
});
|
|
20350
|
-
}, () => {
|
|
20351
|
-
result = env.model.dispatch("SORT_CELLS", {
|
|
20352
|
-
sheetId,
|
|
20353
|
-
col,
|
|
20354
|
-
row,
|
|
20355
|
-
zone,
|
|
20356
|
-
sortDirection,
|
|
20357
|
-
});
|
|
20358
|
-
});
|
|
20359
|
-
}
|
|
20360
|
-
}
|
|
20361
|
-
if (result.isCancelledBecause("InvalidSortZone" /* CommandResult.InvalidSortZone */)) {
|
|
20362
|
-
const { col, row } = anchor;
|
|
20363
|
-
env.model.selection.selectZone({ cell: { col, row }, zone });
|
|
20364
|
-
env.raiseError(_t("Cannot sort. To sort, select only cells or only merges that have the same size."));
|
|
20365
|
-
}
|
|
20366
|
-
}
|
|
20367
|
-
|
|
20368
20590
|
const AddFilterInteractiveContent = {
|
|
20369
20591
|
filterOverlap: _t("You cannot create overlapping filters."),
|
|
20370
20592
|
nonContinuousTargets: _t("A filter can only be created on a continuous selection."),
|
|
@@ -26547,7 +26769,6 @@ css /* scss */ `
|
|
|
26547
26769
|
border-top-right-radius: 4px;
|
|
26548
26770
|
font-size: ${DEFAULT_FONT_SIZE};
|
|
26549
26771
|
color: white;
|
|
26550
|
-
opacity: 0;
|
|
26551
26772
|
pointer-events: none;
|
|
26552
26773
|
}
|
|
26553
26774
|
`;
|
|
@@ -26567,7 +26788,6 @@ class ClientTag extends Component {
|
|
|
26567
26788
|
left: `${x - 1}px`,
|
|
26568
26789
|
border: `1px solid ${color}`,
|
|
26569
26790
|
"background-color": color,
|
|
26570
|
-
opacity: this.props.active ? "opacity:1 !important" : undefined,
|
|
26571
26791
|
});
|
|
26572
26792
|
}
|
|
26573
26793
|
}
|
|
@@ -30113,6 +30333,8 @@ class Grid extends Component {
|
|
|
30113
30333
|
const position = this.env.model.getters.getActivePosition();
|
|
30114
30334
|
this.env.model.selection.selectZone({ cell: position, zone: newZone });
|
|
30115
30335
|
},
|
|
30336
|
+
"CTRL+D": async () => this.env.model.dispatch("COPY_PASTE_CELLS_ABOVE"),
|
|
30337
|
+
"CTRL+R": async () => this.env.model.dispatch("COPY_PASTE_CELLS_ON_LEFT"),
|
|
30116
30338
|
"CTRL+SHIFT+E": () => this.setHorizontalAlign("center"),
|
|
30117
30339
|
"CTRL+SHIFT+L": () => this.setHorizontalAlign("left"),
|
|
30118
30340
|
"CTRL+SHIFT+R": () => this.setHorizontalAlign("right"),
|
|
@@ -40742,7 +40964,7 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
|
|
|
40742
40964
|
return percentile(rangeValues, Number(threshold.value) / 100, true);
|
|
40743
40965
|
case "formula":
|
|
40744
40966
|
const value = threshold.value && this.getters.evaluateFormula(sheetId, threshold.value);
|
|
40745
|
-
return
|
|
40967
|
+
return typeof value === "number" ? value : null;
|
|
40746
40968
|
default:
|
|
40747
40969
|
return null;
|
|
40748
40970
|
}
|
|
@@ -40868,10 +41090,13 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
|
|
|
40868
41090
|
}
|
|
40869
41091
|
const [value0, value1] = rule.values.map((val) => {
|
|
40870
41092
|
if (val.startsWith("=")) {
|
|
40871
|
-
return this.getters.evaluateFormula(target.sheetId, val);
|
|
41093
|
+
return this.getters.evaluateFormula(target.sheetId, val) ?? "";
|
|
40872
41094
|
}
|
|
40873
41095
|
return parseLiteral(val, DEFAULT_LOCALE);
|
|
40874
41096
|
});
|
|
41097
|
+
if (isMatrix(value0) || isMatrix(value1)) {
|
|
41098
|
+
return false;
|
|
41099
|
+
}
|
|
40875
41100
|
switch (rule.operator) {
|
|
40876
41101
|
case "IsEmpty":
|
|
40877
41102
|
return cell.value.toString().trim() === "";
|
|
@@ -41060,7 +41285,7 @@ class EvaluationDataValidationPlugin extends UIPlugin {
|
|
|
41060
41285
|
const formula = compile(value);
|
|
41061
41286
|
const translatedFormula = this.getters.getTranslatedCellFormula(sheetId, offset.col, offset.row, formula, formula.dependencies.map((d) => this.getters.getRangeFromSheetXC(sheetId, d)));
|
|
41062
41287
|
const evaluated = this.getters.evaluateFormula(sheetId, translatedFormula);
|
|
41063
|
-
return evaluated ? evaluated.toString() : "";
|
|
41288
|
+
return evaluated && !isMatrix(evaluated) ? evaluated.toString() : "";
|
|
41064
41289
|
}
|
|
41065
41290
|
catch (e) {
|
|
41066
41291
|
return e instanceof EvaluationError ? e.errorType : CellErrorType.GenericError;
|
|
@@ -46515,6 +46740,20 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
46515
46740
|
const state = new ClipboardOsState(cmd.text, this.getters, this.dispatch, this.selection);
|
|
46516
46741
|
return state.isPasteAllowed(cmd.target, { pasteOption: cmd.pasteOption });
|
|
46517
46742
|
}
|
|
46743
|
+
case "COPY_PASTE_CELLS_ABOVE": {
|
|
46744
|
+
const zones = this.getters.getSelectedZones();
|
|
46745
|
+
if (zones.length > 1 || (zones[0].top === 0 && zones[0].bottom === 0)) {
|
|
46746
|
+
return "InvalidCopyPasteSelection" /* CommandResult.InvalidCopyPasteSelection */;
|
|
46747
|
+
}
|
|
46748
|
+
break;
|
|
46749
|
+
}
|
|
46750
|
+
case "COPY_PASTE_CELLS_ON_LEFT": {
|
|
46751
|
+
const zones = this.getters.getSelectedZones();
|
|
46752
|
+
if (zones.length > 1 || (zones[0].left === 0 && zones[0].right === 0)) {
|
|
46753
|
+
return "InvalidCopyPasteSelection" /* CommandResult.InvalidCopyPasteSelection */;
|
|
46754
|
+
}
|
|
46755
|
+
break;
|
|
46756
|
+
}
|
|
46518
46757
|
case "INSERT_CELL": {
|
|
46519
46758
|
const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
46520
46759
|
const state = this.getClipboardStateForCopyCells(cut, "CUT");
|
|
@@ -46554,6 +46793,40 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
46554
46793
|
this.status = "invisible";
|
|
46555
46794
|
}
|
|
46556
46795
|
break;
|
|
46796
|
+
case "COPY_PASTE_CELLS_ABOVE":
|
|
46797
|
+
{
|
|
46798
|
+
const zone = this.getters.getSelectedZone();
|
|
46799
|
+
const multipleRowsInSelection = zone.top !== zone.bottom;
|
|
46800
|
+
const copyTarget = {
|
|
46801
|
+
...zone,
|
|
46802
|
+
bottom: multipleRowsInSelection ? zone.top : zone.top - 1,
|
|
46803
|
+
top: multipleRowsInSelection ? zone.top : zone.top - 1,
|
|
46804
|
+
};
|
|
46805
|
+
const state = this.getClipboardStateForCopyCells([copyTarget], "COPY");
|
|
46806
|
+
state.paste([zone], {
|
|
46807
|
+
pasteOption: undefined,
|
|
46808
|
+
shouldPasteCF: true,
|
|
46809
|
+
selectTarget: true,
|
|
46810
|
+
});
|
|
46811
|
+
}
|
|
46812
|
+
break;
|
|
46813
|
+
case "COPY_PASTE_CELLS_ON_LEFT":
|
|
46814
|
+
{
|
|
46815
|
+
const zone = this.getters.getSelectedZone();
|
|
46816
|
+
const multipleColsInSelection = zone.left !== zone.right;
|
|
46817
|
+
const copyTarget = {
|
|
46818
|
+
...zone,
|
|
46819
|
+
right: multipleColsInSelection ? zone.left : zone.left - 1,
|
|
46820
|
+
left: multipleColsInSelection ? zone.left : zone.left - 1,
|
|
46821
|
+
};
|
|
46822
|
+
const state = this.getClipboardStateForCopyCells([copyTarget], "COPY");
|
|
46823
|
+
state.paste([zone], {
|
|
46824
|
+
pasteOption: undefined,
|
|
46825
|
+
shouldPasteCF: true,
|
|
46826
|
+
selectTarget: true,
|
|
46827
|
+
});
|
|
46828
|
+
}
|
|
46829
|
+
break;
|
|
46557
46830
|
case "CLEAN_CLIPBOARD_HIGHLIGHT":
|
|
46558
46831
|
this.status = "invisible";
|
|
46559
46832
|
break;
|
|
@@ -47507,6 +47780,9 @@ class EditionPlugin extends UIPlugin {
|
|
|
47507
47780
|
const cellValue = content.startsWith("=")
|
|
47508
47781
|
? this.getters.evaluateFormula(this.sheetId, content)
|
|
47509
47782
|
: parseLiteral(content, this.getters.getLocale());
|
|
47783
|
+
if (isMatrix(cellValue)) {
|
|
47784
|
+
return "Success" /* CommandResult.Success */;
|
|
47785
|
+
}
|
|
47510
47786
|
const validationResult = this.getters.getValidationResultForCellValue(cellValue, cellPosition);
|
|
47511
47787
|
if (!validationResult.isValid && validationResult.rule.isBlocking) {
|
|
47512
47788
|
return "BlockingValidationRule" /* CommandResult.BlockingValidationRule */;
|
|
@@ -48093,11 +48369,19 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
48093
48369
|
}
|
|
48094
48370
|
}
|
|
48095
48371
|
getStatisticFnResults() {
|
|
48096
|
-
|
|
48097
|
-
const cells = new Set(
|
|
48098
|
-
|
|
48099
|
-
|
|
48100
|
-
|
|
48372
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
48373
|
+
const cells = new Set();
|
|
48374
|
+
for (const zone of this.gridSelection.zones) {
|
|
48375
|
+
for (const { col, row } of positions(zone)) {
|
|
48376
|
+
if (this.getters.isRowHidden(sheetId, row) || this.getters.isColHidden(sheetId, col)) {
|
|
48377
|
+
continue; // Skip hidden cells
|
|
48378
|
+
}
|
|
48379
|
+
const evaluatedCell = this.getters.getEvaluatedCell({ sheetId, col, row });
|
|
48380
|
+
if (evaluatedCell.type !== CellValueType.empty) {
|
|
48381
|
+
cells.add(evaluatedCell);
|
|
48382
|
+
}
|
|
48383
|
+
}
|
|
48384
|
+
}
|
|
48101
48385
|
let cellsTypes = new Set();
|
|
48102
48386
|
let cellsValues = [];
|
|
48103
48387
|
for (let cell of cells) {
|
|
@@ -50738,6 +51022,7 @@ const BORDER_POSITIONS = [
|
|
|
50738
51022
|
css /* scss */ `
|
|
50739
51023
|
.o-border-selector {
|
|
50740
51024
|
padding: 4px;
|
|
51025
|
+
background-color: white;
|
|
50741
51026
|
}
|
|
50742
51027
|
.o-divider {
|
|
50743
51028
|
border-right: 1px solid #e0e2e4;
|
|
@@ -55420,6 +55705,6 @@ const constants = {
|
|
|
55420
55705
|
export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
|
|
55421
55706
|
|
|
55422
55707
|
|
|
55423
|
-
__info__.version = "16.5.0-alpha.
|
|
55424
|
-
__info__.date = "2023-10-
|
|
55425
|
-
__info__.hash = "
|
|
55708
|
+
__info__.version = "16.5.0-alpha.13";
|
|
55709
|
+
__info__.date = "2023-10-25T10:04:45.428Z";
|
|
55710
|
+
__info__.hash = "18a08b1";
|