@odoo/o-spreadsheet 17.2.0-alpha.6 → 17.2.0-alpha.8
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 +478 -218
- package/dist/o-spreadsheet.d.ts +156 -119
- package/dist/o-spreadsheet.esm.js +478 -218
- package/dist/o-spreadsheet.iife.js +478 -218
- package/dist/o-spreadsheet.iife.min.js +280 -278
- package/dist/o_spreadsheet.xml +22 -13
- package/package.json +1 -1
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
5
5
|
* @see https://github.com/odoo/o-spreadsheet
|
|
6
|
-
* @version 17.2.0-alpha.
|
|
7
|
-
* @date 2024-
|
|
8
|
-
* @hash
|
|
6
|
+
* @version 17.2.0-alpha.8
|
|
7
|
+
* @date 2024-03-15T11:01:01.388Z
|
|
8
|
+
* @hash 11cf381
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { reactive, useEnv, useSubEnv, useState, onWillUnmount, markRaw, toRaw, Component, useRef, onMounted, useEffect, onPatched, useComponent, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv } from '@odoo/owl';
|
|
@@ -189,8 +189,8 @@ const DEFAULT_GAUGE_LOWER_COLOR = "#cc0000";
|
|
|
189
189
|
const DEFAULT_GAUGE_MIDDLE_COLOR = "#f1c232";
|
|
190
190
|
const DEFAULT_GAUGE_UPPER_COLOR = "#6aa84f";
|
|
191
191
|
const DEFAULT_SCORECARD_BASELINE_MODE = "difference";
|
|
192
|
-
const DEFAULT_SCORECARD_BASELINE_COLOR_UP = "#
|
|
193
|
-
const DEFAULT_SCORECARD_BASELINE_COLOR_DOWN = "#
|
|
192
|
+
const DEFAULT_SCORECARD_BASELINE_COLOR_UP = "#6aa84f";
|
|
193
|
+
const DEFAULT_SCORECARD_BASELINE_COLOR_DOWN = "#E06666";
|
|
194
194
|
const LINE_FILL_TRANSPARENCY = 0.4;
|
|
195
195
|
// session
|
|
196
196
|
const DEBOUNCE_TIME = 200;
|
|
@@ -2144,7 +2144,6 @@ const LAYERS = {
|
|
|
2144
2144
|
Background: 0,
|
|
2145
2145
|
Highlights: 1,
|
|
2146
2146
|
Clipboard: 2,
|
|
2147
|
-
Search: 3,
|
|
2148
2147
|
Chart: 4,
|
|
2149
2148
|
Autofill: 5,
|
|
2150
2149
|
Selection: 6,
|
|
@@ -6316,6 +6315,11 @@ class TableClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
6316
6315
|
this.pasteTableCell(sheetId, tableCell, position, clipboardOptions);
|
|
6317
6316
|
}
|
|
6318
6317
|
}
|
|
6318
|
+
if (tableCells.length === 1) {
|
|
6319
|
+
for (let c = 0; c < tableCells[0].length; c++) {
|
|
6320
|
+
this.dispatch("AUTOFILL_TABLE_COLUMN", { col: col + c, row, sheetId });
|
|
6321
|
+
}
|
|
6322
|
+
}
|
|
6319
6323
|
}
|
|
6320
6324
|
pasteTableCell(sheetId, tableCell, position, options) {
|
|
6321
6325
|
if (tableCell.table && !options?.pasteOption) {
|
|
@@ -7442,6 +7446,7 @@ const TableTerms = {
|
|
|
7442
7446
|
firstColumn: _t("First column"),
|
|
7443
7447
|
lastColumn: _t("Last column"),
|
|
7444
7448
|
bandedColumns: _t("Banded columns"),
|
|
7449
|
+
automaticAutofill: _t("Automatically autofill formulas"),
|
|
7445
7450
|
totalRow: _t("Total row"),
|
|
7446
7451
|
},
|
|
7447
7452
|
Tooltips: {
|
|
@@ -8188,11 +8193,18 @@ function drawHighlight(renderingContext, highlight, rect) {
|
|
|
8188
8193
|
}
|
|
8189
8194
|
const color = highlight.color || HIGHLIGHT_COLOR;
|
|
8190
8195
|
const { ctx } = renderingContext;
|
|
8191
|
-
|
|
8192
|
-
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
+
if (!highlight.noBorder) {
|
|
8197
|
+
ctx.strokeStyle = color;
|
|
8198
|
+
if (highlight.thinLine) {
|
|
8199
|
+
ctx.lineWidth = 1;
|
|
8200
|
+
ctx.strokeRect(x, y, width, height);
|
|
8201
|
+
}
|
|
8202
|
+
else {
|
|
8203
|
+
ctx.lineWidth = 2;
|
|
8204
|
+
/** + 0.5 offset to have sharp lines. See comment in {@link RendererPlugin#drawBorder} for more details */
|
|
8205
|
+
ctx.strokeRect(x + 0.5, y + 0.5, width, height);
|
|
8206
|
+
}
|
|
8207
|
+
}
|
|
8196
8208
|
if (!highlight.noFill) {
|
|
8197
8209
|
ctx.fillStyle = setColorAlpha(color, highlight.fillAlpha ?? 0.12);
|
|
8198
8210
|
ctx.fillRect(x, y, width, height);
|
|
@@ -8566,6 +8578,7 @@ class ComposerStore extends SpreadsheetStore {
|
|
|
8566
8578
|
else if (cell.link) {
|
|
8567
8579
|
content = markdownLink(content, cell.link.url);
|
|
8568
8580
|
}
|
|
8581
|
+
this.addHeadersForSpreadingFormula(content);
|
|
8569
8582
|
this.model.dispatch("UPDATE_CELL", {
|
|
8570
8583
|
sheetId: this.sheetId,
|
|
8571
8584
|
col,
|
|
@@ -8581,6 +8594,7 @@ class ComposerStore extends SpreadsheetStore {
|
|
|
8581
8594
|
row,
|
|
8582
8595
|
});
|
|
8583
8596
|
}
|
|
8597
|
+
this.model.dispatch("AUTOFILL_TABLE_COLUMN", { col, row, sheetId: this.sheetId });
|
|
8584
8598
|
this.setContent("");
|
|
8585
8599
|
}
|
|
8586
8600
|
}
|
|
@@ -8783,6 +8797,38 @@ class ComposerStore extends SpreadsheetStore {
|
|
|
8783
8797
|
}
|
|
8784
8798
|
this.colorIndexByRange = colorsToKeep;
|
|
8785
8799
|
}
|
|
8800
|
+
/** Add headers at the end of the sheet so the formula in the composer has enough space to spread */
|
|
8801
|
+
addHeadersForSpreadingFormula(content) {
|
|
8802
|
+
if (!content.startsWith("=")) {
|
|
8803
|
+
return;
|
|
8804
|
+
}
|
|
8805
|
+
const evaluated = this.getters.evaluateFormula(this.sheetId, content);
|
|
8806
|
+
if (!isMatrix(evaluated)) {
|
|
8807
|
+
return;
|
|
8808
|
+
}
|
|
8809
|
+
const numberOfRows = this.getters.getNumberRows(this.sheetId);
|
|
8810
|
+
const numberOfCols = this.getters.getNumberCols(this.sheetId);
|
|
8811
|
+
const missingRows = this.row + evaluated[0].length - numberOfRows;
|
|
8812
|
+
const missingCols = this.col + evaluated.length - numberOfCols;
|
|
8813
|
+
if (missingCols > 0) {
|
|
8814
|
+
this.model.dispatch("ADD_COLUMNS_ROWS", {
|
|
8815
|
+
sheetId: this.sheetId,
|
|
8816
|
+
dimension: "COL",
|
|
8817
|
+
base: numberOfCols - 1,
|
|
8818
|
+
position: "after",
|
|
8819
|
+
quantity: missingCols + 20,
|
|
8820
|
+
});
|
|
8821
|
+
}
|
|
8822
|
+
if (missingRows > 0) {
|
|
8823
|
+
this.model.dispatch("ADD_COLUMNS_ROWS", {
|
|
8824
|
+
sheetId: this.sheetId,
|
|
8825
|
+
dimension: "ROW",
|
|
8826
|
+
base: numberOfRows - 1,
|
|
8827
|
+
position: "after",
|
|
8828
|
+
quantity: missingRows + 50,
|
|
8829
|
+
});
|
|
8830
|
+
}
|
|
8831
|
+
}
|
|
8786
8832
|
/**
|
|
8787
8833
|
* Highlight all ranges that can be found in the composer content.
|
|
8788
8834
|
*/
|
|
@@ -17416,10 +17462,11 @@ const DEFAULT_IS_SORTED = true;
|
|
|
17416
17462
|
const DEFAULT_MATCH_MODE = 0;
|
|
17417
17463
|
const DEFAULT_SEARCH_MODE = 1;
|
|
17418
17464
|
const DEFAULT_ABSOLUTE_RELATIVE_MODE = 1;
|
|
17419
|
-
function
|
|
17420
|
-
|
|
17421
|
-
|
|
17422
|
-
|
|
17465
|
+
function valueNotAvailable(searchKey) {
|
|
17466
|
+
return {
|
|
17467
|
+
value: CellErrorType.NotAvailable,
|
|
17468
|
+
message: _t("Did not find value '%s' in [[FUNCTION_NAME]] evaluation.", toString(searchKey)),
|
|
17469
|
+
};
|
|
17423
17470
|
}
|
|
17424
17471
|
// -----------------------------------------------------------------------------
|
|
17425
17472
|
// ADDRESS
|
|
@@ -17516,7 +17563,9 @@ const HLOOKUP = {
|
|
|
17516
17563
|
? dichotomicSearch(range, searchKey, "nextSmaller", "asc", range.length, getValueFromRange)
|
|
17517
17564
|
: linearSearch(range, searchKey, "wildcard", range.length, getValueFromRange);
|
|
17518
17565
|
const col = range[colIndex];
|
|
17519
|
-
|
|
17566
|
+
if (col === undefined) {
|
|
17567
|
+
return valueNotAvailable(searchKey);
|
|
17568
|
+
}
|
|
17520
17569
|
return col[_index - 1];
|
|
17521
17570
|
},
|
|
17522
17571
|
isExported: true,
|
|
@@ -17635,11 +17684,11 @@ const LOOKUP = {
|
|
|
17635
17684
|
: (range, index) => range[index][0].value;
|
|
17636
17685
|
const rangeLength = verticalSearch ? nbRow : nbCol;
|
|
17637
17686
|
const index = dichotomicSearch(searchArray, searchKey, "nextSmaller", "asc", rangeLength, getElement);
|
|
17638
|
-
if (index === -1
|
|
17639
|
-
|
|
17640
|
-
|
|
17641
|
-
|
|
17642
|
-
|
|
17687
|
+
if (index === -1 ||
|
|
17688
|
+
(verticalSearch && searchArray[0][index] === undefined) ||
|
|
17689
|
+
(!verticalSearch && searchArray[index][nbRow - 1] === undefined)) {
|
|
17690
|
+
return valueNotAvailable(searchKey);
|
|
17691
|
+
}
|
|
17643
17692
|
if (resultRange === undefined) {
|
|
17644
17693
|
return verticalSearch ? searchArray[nbCol - 1][index] : searchArray[index][nbRow - 1];
|
|
17645
17694
|
}
|
|
@@ -17689,7 +17738,10 @@ const MATCH = {
|
|
|
17689
17738
|
index = dichotomicSearch(range, searchKey, "nextGreater", "desc", rangeLen, getElement);
|
|
17690
17739
|
break;
|
|
17691
17740
|
}
|
|
17692
|
-
|
|
17741
|
+
if ((nbCol === 1 && range[0][index] === undefined) ||
|
|
17742
|
+
(nbCol !== 1 && range[index] === undefined)) {
|
|
17743
|
+
return valueNotAvailable(searchKey);
|
|
17744
|
+
}
|
|
17693
17745
|
return index + 1;
|
|
17694
17746
|
},
|
|
17695
17747
|
isExported: true,
|
|
@@ -17748,7 +17800,9 @@ const VLOOKUP = {
|
|
|
17748
17800
|
? dichotomicSearch(range, searchKey, "nextSmaller", "asc", range[0].length, getValueFromRange)
|
|
17749
17801
|
: linearSearch(range, searchKey, "wildcard", range[0].length, getValueFromRange);
|
|
17750
17802
|
const value = range[_index - 1][rowIndex];
|
|
17751
|
-
|
|
17803
|
+
if (value === undefined) {
|
|
17804
|
+
return valueNotAvailable(searchKey);
|
|
17805
|
+
}
|
|
17752
17806
|
return value;
|
|
17753
17807
|
},
|
|
17754
17808
|
isExported: true,
|
|
@@ -17808,7 +17862,9 @@ const XLOOKUP = {
|
|
|
17808
17862
|
? returnRange.map((col) => [col[index]])
|
|
17809
17863
|
: [returnRange[index]];
|
|
17810
17864
|
}
|
|
17811
|
-
|
|
17865
|
+
if (defaultValue === undefined) {
|
|
17866
|
+
return valueNotAvailable(searchKey);
|
|
17867
|
+
}
|
|
17812
17868
|
return [[defaultValue]];
|
|
17813
17869
|
},
|
|
17814
17870
|
isExported: true,
|
|
@@ -18575,8 +18631,7 @@ class FunctionRegistry extends Registry {
|
|
|
18575
18631
|
function addErrorHandling(compute, functionName) {
|
|
18576
18632
|
return function (...args) {
|
|
18577
18633
|
try {
|
|
18578
|
-
|
|
18579
|
-
return computeFormula(...args);
|
|
18634
|
+
return compute.apply(this, args);
|
|
18580
18635
|
}
|
|
18581
18636
|
catch (e) {
|
|
18582
18637
|
return handleError(e, functionName);
|
|
@@ -18610,8 +18665,7 @@ function hasStringMessage(obj) {
|
|
|
18610
18665
|
}
|
|
18611
18666
|
function addResultHandling(compute) {
|
|
18612
18667
|
return function (...args) {
|
|
18613
|
-
const
|
|
18614
|
-
const result = computeResult(...args);
|
|
18668
|
+
const result = compute.apply(this, args);
|
|
18615
18669
|
if (!isMatrix(result)) {
|
|
18616
18670
|
if (typeof result === "object" && result !== null && "value" in result) {
|
|
18617
18671
|
return result;
|
|
@@ -18826,8 +18880,10 @@ function getGroup(cell, cells, filter) {
|
|
|
18826
18880
|
if (x === cell) {
|
|
18827
18881
|
found = true;
|
|
18828
18882
|
}
|
|
18829
|
-
const cellValue =
|
|
18830
|
-
|
|
18883
|
+
const cellValue = x?.isFormula
|
|
18884
|
+
? undefined
|
|
18885
|
+
: evaluateLiteral(x?.content, { locale: DEFAULT_LOCALE });
|
|
18886
|
+
if (cellValue && filter(cellValue)) {
|
|
18831
18887
|
group.push(cellValue);
|
|
18832
18888
|
}
|
|
18833
18889
|
else {
|
|
@@ -19476,9 +19532,15 @@ function getChartDatasetValues(getters, dataSets) {
|
|
|
19476
19532
|
: (label = `${ChartTerms.Series} ${parseInt(dsIndex) + 1}`);
|
|
19477
19533
|
}
|
|
19478
19534
|
else {
|
|
19479
|
-
label =
|
|
19535
|
+
label = `${ChartTerms.Series} ${parseInt(dsIndex) + 1}`;
|
|
19480
19536
|
}
|
|
19481
19537
|
let data = ds.dataRange ? getData(getters, ds) : [];
|
|
19538
|
+
if (data.every((e) => typeof e === "string" && !isEvaluationError(e))) {
|
|
19539
|
+
// In this case, we want a chart based on the string occurrences count
|
|
19540
|
+
// This will be done by associating each string with a value of 1 and
|
|
19541
|
+
// the using the classical aggregation method to sum the values.
|
|
19542
|
+
data.fill(1);
|
|
19543
|
+
}
|
|
19482
19544
|
datasetValues.push({ data, label });
|
|
19483
19545
|
}
|
|
19484
19546
|
return datasetValues;
|
|
@@ -19577,7 +19639,7 @@ class BarChart extends AbstractChart {
|
|
|
19577
19639
|
dataSets: context.range ? context.range : [],
|
|
19578
19640
|
dataSetsHaveTitle: false,
|
|
19579
19641
|
stacked: false,
|
|
19580
|
-
aggregated: false,
|
|
19642
|
+
aggregated: context.aggregated ?? false,
|
|
19581
19643
|
legendPosition: "top",
|
|
19582
19644
|
title: context.title || "",
|
|
19583
19645
|
type: "bar",
|
|
@@ -19593,6 +19655,7 @@ class BarChart extends AbstractChart {
|
|
|
19593
19655
|
auxiliaryRange: this.labelRange
|
|
19594
19656
|
? this.getters.getRangeString(this.labelRange, this.sheetId)
|
|
19595
19657
|
: undefined,
|
|
19658
|
+
aggregated: this.aggregated,
|
|
19596
19659
|
};
|
|
19597
19660
|
}
|
|
19598
19661
|
copyForSheetId(sheetId) {
|
|
@@ -20342,7 +20405,7 @@ class LineChart extends AbstractChart {
|
|
|
20342
20405
|
verticalAxisPosition: "left",
|
|
20343
20406
|
labelRange: context.auxiliaryRange || undefined,
|
|
20344
20407
|
stacked: false,
|
|
20345
|
-
aggregated: false,
|
|
20408
|
+
aggregated: context.aggregated ?? false,
|
|
20346
20409
|
cumulative: false,
|
|
20347
20410
|
};
|
|
20348
20411
|
}
|
|
@@ -20375,6 +20438,7 @@ class LineChart extends AbstractChart {
|
|
|
20375
20438
|
auxiliaryRange: this.labelRange
|
|
20376
20439
|
? this.getters.getRangeString(this.labelRange, this.sheetId)
|
|
20377
20440
|
: undefined,
|
|
20441
|
+
aggregated: this.aggregated,
|
|
20378
20442
|
};
|
|
20379
20443
|
}
|
|
20380
20444
|
updateRanges(applyChange) {
|
|
@@ -20449,7 +20513,7 @@ class PieChart extends AbstractChart {
|
|
|
20449
20513
|
title: context.title || "",
|
|
20450
20514
|
type: "pie",
|
|
20451
20515
|
labelRange: context.auxiliaryRange || undefined,
|
|
20452
|
-
aggregated: false,
|
|
20516
|
+
aggregated: context.aggregated ?? false,
|
|
20453
20517
|
};
|
|
20454
20518
|
}
|
|
20455
20519
|
getDefinition() {
|
|
@@ -20463,6 +20527,7 @@ class PieChart extends AbstractChart {
|
|
|
20463
20527
|
auxiliaryRange: this.labelRange
|
|
20464
20528
|
? this.getters.getRangeString(this.labelRange, this.sheetId)
|
|
20465
20529
|
: undefined,
|
|
20530
|
+
aggregated: this.aggregated,
|
|
20466
20531
|
};
|
|
20467
20532
|
}
|
|
20468
20533
|
getDefinitionWithSpecificDataSets(dataSets, labelRange, targetSheetId) {
|
|
@@ -20654,7 +20719,7 @@ class ScatterChart extends AbstractChart {
|
|
|
20654
20719
|
type: "scatter",
|
|
20655
20720
|
verticalAxisPosition: "left",
|
|
20656
20721
|
labelRange: context.auxiliaryRange || undefined,
|
|
20657
|
-
aggregated: false,
|
|
20722
|
+
aggregated: context.aggregated ?? false,
|
|
20658
20723
|
};
|
|
20659
20724
|
}
|
|
20660
20725
|
getDefinition() {
|
|
@@ -20684,6 +20749,7 @@ class ScatterChart extends AbstractChart {
|
|
|
20684
20749
|
auxiliaryRange: this.labelRange
|
|
20685
20750
|
? this.getters.getRangeString(this.labelRange, this.sheetId)
|
|
20686
20751
|
: undefined,
|
|
20752
|
+
aggregated: this.aggregated,
|
|
20687
20753
|
};
|
|
20688
20754
|
}
|
|
20689
20755
|
updateRanges(applyChange) {
|
|
@@ -22351,6 +22417,50 @@ function isCtrlKey(ev) {
|
|
|
22351
22417
|
return isMacOS() ? ev.metaKey : ev.ctrlKey;
|
|
22352
22418
|
}
|
|
22353
22419
|
|
|
22420
|
+
/**
|
|
22421
|
+
* Repeatedly calls a callback function with a time delay between calls.
|
|
22422
|
+
*/
|
|
22423
|
+
function useInterval(callback, delay) {
|
|
22424
|
+
let intervalId;
|
|
22425
|
+
const { setInterval, clearInterval } = window;
|
|
22426
|
+
useEffect(() => {
|
|
22427
|
+
intervalId = setInterval(callback, delay);
|
|
22428
|
+
return () => clearInterval(intervalId);
|
|
22429
|
+
}, () => [delay]);
|
|
22430
|
+
return {
|
|
22431
|
+
pause: () => {
|
|
22432
|
+
clearInterval(intervalId);
|
|
22433
|
+
intervalId = undefined;
|
|
22434
|
+
},
|
|
22435
|
+
resume: () => {
|
|
22436
|
+
if (intervalId === undefined) {
|
|
22437
|
+
intervalId = setInterval(callback, delay);
|
|
22438
|
+
}
|
|
22439
|
+
},
|
|
22440
|
+
};
|
|
22441
|
+
}
|
|
22442
|
+
/**
|
|
22443
|
+
* Calls a callback function with a time delay
|
|
22444
|
+
*/
|
|
22445
|
+
function useTimeOut() {
|
|
22446
|
+
let timeOutId;
|
|
22447
|
+
function clear() {
|
|
22448
|
+
if (timeOutId !== undefined) {
|
|
22449
|
+
clearTimeout(timeOutId);
|
|
22450
|
+
timeOutId = undefined;
|
|
22451
|
+
}
|
|
22452
|
+
}
|
|
22453
|
+
function schedule(callback, delay) {
|
|
22454
|
+
clear();
|
|
22455
|
+
timeOutId = setTimeout(callback, delay);
|
|
22456
|
+
}
|
|
22457
|
+
onWillUnmount(clear);
|
|
22458
|
+
return {
|
|
22459
|
+
clear,
|
|
22460
|
+
schedule,
|
|
22461
|
+
};
|
|
22462
|
+
}
|
|
22463
|
+
|
|
22354
22464
|
//------------------------------------------------------------------------------
|
|
22355
22465
|
// Context Menu Component
|
|
22356
22466
|
//------------------------------------------------------------------------------
|
|
@@ -22401,6 +22511,7 @@ css /* scss */ `
|
|
|
22401
22511
|
}
|
|
22402
22512
|
}
|
|
22403
22513
|
`;
|
|
22514
|
+
const TIMEOUT_DELAY = 250;
|
|
22404
22515
|
class Menu extends Component {
|
|
22405
22516
|
static template = "o-spreadsheet-Menu";
|
|
22406
22517
|
static props = {
|
|
@@ -22411,6 +22522,7 @@ class Menu extends Component {
|
|
|
22411
22522
|
onClose: Function,
|
|
22412
22523
|
onMenuClicked: { type: Function, optional: true },
|
|
22413
22524
|
menuId: { type: String, optional: true },
|
|
22525
|
+
onMouseOver: { type: Function, optional: true },
|
|
22414
22526
|
};
|
|
22415
22527
|
static components = { Menu, Popover };
|
|
22416
22528
|
static defaultProps = {
|
|
@@ -22421,10 +22533,12 @@ class Menu extends Component {
|
|
|
22421
22533
|
position: null,
|
|
22422
22534
|
scrollOffset: 0,
|
|
22423
22535
|
menuItems: [],
|
|
22536
|
+
isHoveringChild: false,
|
|
22424
22537
|
});
|
|
22425
22538
|
menuRef = useRef("menu");
|
|
22426
22539
|
hoveredMenu = undefined;
|
|
22427
22540
|
position = useAbsoluteBoundingRect(this.menuRef);
|
|
22541
|
+
openingTimeOut = useTimeOut();
|
|
22428
22542
|
setup() {
|
|
22429
22543
|
useExternalListener(window, "click", this.onExternalClick, { capture: true });
|
|
22430
22544
|
useExternalListener(window, "contextmenu", this.onExternalClick, { capture: true });
|
|
@@ -22524,6 +22638,9 @@ class Menu extends Component {
|
|
|
22524
22638
|
}
|
|
22525
22639
|
return false;
|
|
22526
22640
|
}
|
|
22641
|
+
isActive(menuItem) {
|
|
22642
|
+
return (this.subMenu?.isHoveringChild || false) && this.isParentMenu(this.subMenu, menuItem);
|
|
22643
|
+
}
|
|
22527
22644
|
onScroll(ev) {
|
|
22528
22645
|
this.subMenu.scrollOffset = ev.target.scrollTop;
|
|
22529
22646
|
}
|
|
@@ -22531,10 +22648,10 @@ class Menu extends Component {
|
|
|
22531
22648
|
* If the given menu is not disabled, open it's submenu at the
|
|
22532
22649
|
* correct position according to available surrounding space.
|
|
22533
22650
|
*/
|
|
22534
|
-
openSubMenu(menu,
|
|
22535
|
-
|
|
22536
|
-
if (!parentMenuEl)
|
|
22651
|
+
openSubMenu(menu, parentMenuEl) {
|
|
22652
|
+
if (!parentMenuEl) {
|
|
22537
22653
|
return;
|
|
22654
|
+
}
|
|
22538
22655
|
const y = parentMenuEl.getBoundingClientRect().top;
|
|
22539
22656
|
this.subMenu.position = {
|
|
22540
22657
|
x: this.position.x + this.props.depth * MENU_WIDTH,
|
|
@@ -22548,32 +22665,50 @@ class Menu extends Component {
|
|
|
22548
22665
|
return subMenu.parentMenu?.id === menuItem.id;
|
|
22549
22666
|
}
|
|
22550
22667
|
closeSubMenu() {
|
|
22668
|
+
if (this.subMenu.isHoveringChild) {
|
|
22669
|
+
return;
|
|
22670
|
+
}
|
|
22551
22671
|
this.subMenu.isOpen = false;
|
|
22552
22672
|
this.subMenu.parentMenu = undefined;
|
|
22553
22673
|
}
|
|
22554
22674
|
onClickMenu(menu, ev) {
|
|
22555
22675
|
if (this.isEnabled(menu)) {
|
|
22556
22676
|
if (this.isRoot(menu)) {
|
|
22557
|
-
this.openSubMenu(menu, ev);
|
|
22677
|
+
this.openSubMenu(menu, ev.currentTarget);
|
|
22558
22678
|
}
|
|
22559
22679
|
else {
|
|
22560
22680
|
this.activateMenu(menu);
|
|
22561
22681
|
}
|
|
22562
22682
|
}
|
|
22563
22683
|
}
|
|
22564
|
-
|
|
22565
|
-
this.hoveredMenu = menu;
|
|
22566
|
-
menu.onStartHover?.(this.env);
|
|
22684
|
+
onMouseOver(menu, ev) {
|
|
22567
22685
|
if (this.isEnabled(menu)) {
|
|
22568
|
-
if (this.
|
|
22569
|
-
this.
|
|
22686
|
+
if (this.isParentMenu(this.subMenu, menu)) {
|
|
22687
|
+
this.openingTimeOut.clear();
|
|
22688
|
+
return;
|
|
22570
22689
|
}
|
|
22571
|
-
|
|
22572
|
-
|
|
22690
|
+
const currentTarget = ev.currentTarget;
|
|
22691
|
+
if (this.isRoot(menu)) {
|
|
22692
|
+
this.openingTimeOut.schedule(() => {
|
|
22693
|
+
this.openSubMenu(menu, currentTarget);
|
|
22694
|
+
}, TIMEOUT_DELAY);
|
|
22573
22695
|
}
|
|
22574
22696
|
}
|
|
22575
22697
|
}
|
|
22698
|
+
onMouseOverMainMenu() {
|
|
22699
|
+
this.props.onMouseOver?.();
|
|
22700
|
+
this.subMenu.isHoveringChild = false;
|
|
22701
|
+
}
|
|
22702
|
+
onMouseOverChildMenu() {
|
|
22703
|
+
this.subMenu.isHoveringChild = true;
|
|
22704
|
+
this.openingTimeOut.clear();
|
|
22705
|
+
}
|
|
22706
|
+
onMouseEnter(menu, ev) {
|
|
22707
|
+
this.hoveredMenu = menu;
|
|
22708
|
+
menu.onStartHover?.(this.env);
|
|
22709
|
+
}
|
|
22576
22710
|
onMouseLeave(menu) {
|
|
22711
|
+
this.openingTimeOut.schedule(this.closeSubMenu.bind(this), TIMEOUT_DELAY);
|
|
22577
22712
|
this.hoveredMenu = undefined;
|
|
22578
22713
|
menu.onStopHover?.(this.env);
|
|
22579
22714
|
}
|
|
@@ -22825,7 +22960,8 @@ function getChartTypes() {
|
|
|
22825
22960
|
*/
|
|
22826
22961
|
function getSmartChartDefinition(zone, getters) {
|
|
22827
22962
|
let dataSetZone = zone;
|
|
22828
|
-
|
|
22963
|
+
const singleColumn = zoneToDimension(zone).numberOfCols === 1;
|
|
22964
|
+
if (!singleColumn) {
|
|
22829
22965
|
dataSetZone = { ...zone, left: zone.left + 1 };
|
|
22830
22966
|
}
|
|
22831
22967
|
const dataSets = [zoneToXc(dataSetZone)];
|
|
@@ -22859,7 +22995,7 @@ function getSmartChartDefinition(zone, getters) {
|
|
|
22859
22995
|
}
|
|
22860
22996
|
}
|
|
22861
22997
|
let labelRangeXc;
|
|
22862
|
-
if (
|
|
22998
|
+
if (!singleColumn) {
|
|
22863
22999
|
labelRangeXc = zoneToXc({
|
|
22864
23000
|
...zone,
|
|
22865
23001
|
right: zone.left,
|
|
@@ -22883,6 +23019,19 @@ function getSmartChartDefinition(zone, getters) {
|
|
|
22883
23019
|
legendPosition: newLegendPos,
|
|
22884
23020
|
};
|
|
22885
23021
|
}
|
|
23022
|
+
const _dataSets = createDataSets(getters, dataSets, sheetId, dataSetsHaveTitle);
|
|
23023
|
+
if (singleColumn &&
|
|
23024
|
+
getData(getters, _dataSets[0]).every((e) => typeof e === "string" && !isEvaluationError(e))) {
|
|
23025
|
+
return {
|
|
23026
|
+
title: "",
|
|
23027
|
+
dataSets,
|
|
23028
|
+
aggregated: true,
|
|
23029
|
+
labelRange: dataSets[0],
|
|
23030
|
+
type: "pie",
|
|
23031
|
+
legendPosition: "top",
|
|
23032
|
+
dataSetsHaveTitle: false,
|
|
23033
|
+
};
|
|
23034
|
+
}
|
|
22886
23035
|
return {
|
|
22887
23036
|
title,
|
|
22888
23037
|
dataSets,
|
|
@@ -22910,6 +23059,7 @@ const DEFAULT_TABLE_CONFIG = {
|
|
|
22910
23059
|
numberOfHeaders: 1,
|
|
22911
23060
|
bandedRows: true,
|
|
22912
23061
|
bandedColumns: false,
|
|
23062
|
+
automaticAutofill: true,
|
|
22913
23063
|
styleId: "TableStyleMedium2",
|
|
22914
23064
|
};
|
|
22915
23065
|
function generateColorSet(name, highlightColor) {
|
|
@@ -26393,7 +26543,7 @@ class LineBarPieConfigPanel extends Component {
|
|
|
26393
26543
|
{
|
|
26394
26544
|
name: "aggregated",
|
|
26395
26545
|
label: _t("Aggregate"),
|
|
26396
|
-
value: this.props.definition.aggregated,
|
|
26546
|
+
value: this.props.definition.aggregated ?? false,
|
|
26397
26547
|
onChange: this.onUpdateAggregated.bind(this),
|
|
26398
26548
|
},
|
|
26399
26549
|
];
|
|
@@ -27564,15 +27714,15 @@ css /* scss */ `
|
|
|
27564
27714
|
// -----------------------------------------------------------------------------
|
|
27565
27715
|
// We need here the svg of the icons that we need to convert to images for the renderer
|
|
27566
27716
|
// -----------------------------------------------------------------------------
|
|
27567
|
-
const ARROW_DOWN = '<svg class="o-cf-icon arrow-down" width="10" height="10" focusable="false" viewBox="0 0 448 512"><path fill="#
|
|
27568
|
-
const ARROW_UP = '<svg class="o-cf-icon arrow-up" width="10" height="10" focusable="false" viewBox="0 0 448 512"><path fill="#
|
|
27717
|
+
const ARROW_DOWN = '<svg class="o-cf-icon arrow-down" width="10" height="10" focusable="false" viewBox="0 0 448 512"><path fill="#E06666" d="M413.1 222.5l22.2 22.2c9.4 9.4 9.4 24.6 0 33.9L241 473c-9.4 9.4-24.6 9.4-33.9 0L12.7 278.6c-9.4-9.4-9.4-24.6 0-33.9l22.2-22.2c9.5-9.5 25-9.3 34.3.4L184 343.4V56c0-13.3 10.7-24 24-24h32c13.3 0 24 10.7 24 24v287.4l114.8-120.5c9.3-9.8 24.8-10 34.3-.4z"></path></svg>';
|
|
27718
|
+
const ARROW_UP = '<svg class="o-cf-icon arrow-up" width="10" height="10" focusable="false" viewBox="0 0 448 512"><path fill="#6AA84F" d="M34.9 289.5l-22.2-22.2c-9.4-9.4-9.4-24.6 0-33.9L207 39c9.4-9.4 24.6-9.4 33.9 0l194.3 194.3c9.4 9.4 9.4 24.6 0 33.9L413 289.4c-9.5 9.5-25 9.3-34.3-.4L264 168.6V456c0 13.3-10.7 24-24 24h-32c-13.3 0-24-10.7-24-24V168.6L69.2 289.1c-9.3 9.8-24.8 10-34.3.4z"></path></svg>';
|
|
27569
27719
|
const ARROW_RIGHT = '<svg class="o-cf-icon arrow-right" width="10" height="10" focusable="false" viewBox="0 0 448 512"><path fill="#F0AD4E" d="M190.5 66.9l22.2-22.2c9.4-9.4 24.6-9.4 33.9 0L441 239c9.4 9.4 9.4 24.6 0 33.9L246.6 467.3c-9.4 9.4-24.6 9.4-33.9 0l-22.2-22.2c-9.5-9.5-9.3-25 .4-34.3L311.4 296H24c-13.3 0-24-10.7-24-24v-32c0-13.3 10.7-24 24-24h287.4L190.9 101.2c-9.8-9.3-10-24.8-.4-34.3z"></path></svg>';
|
|
27570
|
-
const SMILE = '<svg class="o-cf-icon smile" width="10" height="10" focusable="false" viewBox="0 0 496 512"><path fill="#
|
|
27720
|
+
const SMILE = '<svg class="o-cf-icon smile" width="10" height="10" focusable="false" viewBox="0 0 496 512"><path fill="#6AA84F" d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160 0c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm4 72.6c-20.8 25-51.5 39.4-84 39.4s-63.2-14.3-84-39.4c-8.5-10.2-23.7-11.5-33.8-3.1-10.2 8.5-11.5 23.6-3.1 33.8 30 36 74.1 56.6 120.9 56.6s90.9-20.6 120.9-56.6c8.5-10.2 7.1-25.3-3.1-33.8-10.1-8.4-25.3-7.1-33.8 3.1z"></path></svg>';
|
|
27571
27721
|
const MEH = '<svg class="o-cf-icon meh" width="10" height="10" focusable="false" viewBox="0 0 496 512"><path fill="#F0AD4E" d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160-64c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm8 144H160c-13.2 0-24 10.8-24 24s10.8 24 24 24h176c13.2 0 24-10.8 24-24s-10.8-24-24-24z"></path></svg>';
|
|
27572
|
-
const FROWN = '<svg class="o-cf-icon frown" width="10" height="10" focusable="false" viewBox="0 0 496 512"><path fill="#
|
|
27573
|
-
const GREEN_DOT = '<svg class="o-cf-icon green-dot" width="10" height="10" focusable="false" viewBox="0 0 512 512"><path fill="#
|
|
27722
|
+
const FROWN = '<svg class="o-cf-icon frown" width="10" height="10" focusable="false" viewBox="0 0 496 512"><path fill="#E06666" d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160-64c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm-80 128c-40.2 0-78 17.7-103.8 48.6-8.5 10.2-7.1 25.3 3.1 33.8 10.2 8.4 25.3 7.1 33.8-3.1 16.6-19.9 41-31.4 66.9-31.4s50.3 11.4 66.9 31.4c8.1 9.7 23.1 11.9 33.8 3.1 10.2-8.5 11.5-23.6 3.1-33.8C326 321.7 288.2 304 248 304z"></path></svg>';
|
|
27723
|
+
const GREEN_DOT = '<svg class="o-cf-icon green-dot" width="10" height="10" focusable="false" viewBox="0 0 512 512"><path fill="#6AA84F" d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z"></path></svg>';
|
|
27574
27724
|
const YELLOW_DOT = '<svg class="o-cf-icon yellow-dot" width="10" height="10" focusable="false" viewBox="0 0 512 512"><path fill="#F0AD4E" d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z"></path></svg>';
|
|
27575
|
-
const RED_DOT = '<svg class="o-cf-icon red-dot" width="10" height="10" focusable="false" viewBox="0 0 512 512"><path fill="#
|
|
27725
|
+
const RED_DOT = '<svg class="o-cf-icon red-dot" width="10" height="10" focusable="false" viewBox="0 0 512 512"><path fill="#E06666" d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z"></path></svg>';
|
|
27576
27726
|
function loadIconImage(svg) {
|
|
27577
27727
|
/** We have to add xmlns, as it's not added by owl in the canvas */
|
|
27578
27728
|
svg = `<svg xmlns="http://www.w3.org/2000/svg" ${svg.slice(4)}`;
|
|
@@ -29438,8 +29588,7 @@ class DataValidationPanel extends Component {
|
|
|
29438
29588
|
}
|
|
29439
29589
|
}
|
|
29440
29590
|
|
|
29441
|
-
const
|
|
29442
|
-
const BACKGROUND_COLOR = "#8B008B33";
|
|
29591
|
+
const FIND_AND_REPLACE_HIGHLIGHT_COLOR = "#8B008B";
|
|
29443
29592
|
var Direction;
|
|
29444
29593
|
(function (Direction) {
|
|
29445
29594
|
Direction[Direction["previous"] = -1] = "previous";
|
|
@@ -29470,14 +29619,14 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
29470
29619
|
super(get);
|
|
29471
29620
|
this.initialShowFormulaState = this.model.getters.shouldShowFormulas();
|
|
29472
29621
|
this.searchOptions.searchFormulas = this.initialShowFormulaState;
|
|
29622
|
+
const highlightStore = get(HighlightStore);
|
|
29623
|
+
highlightStore.register(toRaw(this));
|
|
29473
29624
|
this.onDispose(() => {
|
|
29474
29625
|
this.model.dispatch("SET_FORMULA_VISIBILITY", { show: this.initialShowFormulaState });
|
|
29475
29626
|
this.updateSearchContent.stopDebounce();
|
|
29627
|
+
highlightStore.unRegister(toRaw(this));
|
|
29476
29628
|
});
|
|
29477
29629
|
}
|
|
29478
|
-
get renderingLayers() {
|
|
29479
|
-
return ["Search"];
|
|
29480
|
-
}
|
|
29481
29630
|
get searchMatches() {
|
|
29482
29631
|
switch (this.searchOptions.searchScope) {
|
|
29483
29632
|
case "allSheets":
|
|
@@ -29704,8 +29853,8 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
29704
29853
|
// ---------------------------------------------------------------------------
|
|
29705
29854
|
// Grid rendering
|
|
29706
29855
|
// ---------------------------------------------------------------------------
|
|
29707
|
-
|
|
29708
|
-
const
|
|
29856
|
+
get highlights() {
|
|
29857
|
+
const highlights = [];
|
|
29709
29858
|
const sheetId = this.getters.getActiveSheetId();
|
|
29710
29859
|
for (const [index, match] of this.searchMatches.entries()) {
|
|
29711
29860
|
if (match.sheetId !== sheetId) {
|
|
@@ -29713,26 +29862,31 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
29713
29862
|
}
|
|
29714
29863
|
const zone = positionToZone(match);
|
|
29715
29864
|
const zoneWithMerge = this.getters.expandZone(sheetId, zone);
|
|
29716
|
-
const {
|
|
29865
|
+
const { width, height } = this.getters.getVisibleRect(zoneWithMerge);
|
|
29717
29866
|
if (width > 0 && height > 0) {
|
|
29718
|
-
|
|
29719
|
-
|
|
29720
|
-
|
|
29721
|
-
|
|
29722
|
-
|
|
29723
|
-
|
|
29867
|
+
highlights.push({
|
|
29868
|
+
sheetId,
|
|
29869
|
+
zone: zoneWithMerge,
|
|
29870
|
+
color: FIND_AND_REPLACE_HIGHLIGHT_COLOR,
|
|
29871
|
+
noBorder: index !== this.selectedMatchIndex,
|
|
29872
|
+
thinLine: true,
|
|
29873
|
+
fillAlpha: 0.2,
|
|
29874
|
+
});
|
|
29724
29875
|
}
|
|
29725
29876
|
}
|
|
29726
|
-
// TODO: use Highlights helpers/stores when the Highlight PR is merged
|
|
29727
29877
|
if (this.searchOptions.searchScope === "specificRange") {
|
|
29728
29878
|
const range = this.searchOptions.specificRange;
|
|
29729
|
-
if (
|
|
29730
|
-
|
|
29879
|
+
if (range && range.sheetId === sheetId) {
|
|
29880
|
+
highlights.push({
|
|
29881
|
+
sheetId,
|
|
29882
|
+
zone: range.zone,
|
|
29883
|
+
color: FIND_AND_REPLACE_HIGHLIGHT_COLOR,
|
|
29884
|
+
noFill: true,
|
|
29885
|
+
thinLine: true,
|
|
29886
|
+
});
|
|
29731
29887
|
}
|
|
29732
|
-
const { x, y, width, height } = this.getters.getVisibleRect(range.zone);
|
|
29733
|
-
ctx.strokeStyle = BORDER_COLOR;
|
|
29734
|
-
ctx.strokeRect(x, y, width, height);
|
|
29735
29888
|
}
|
|
29889
|
+
return highlights;
|
|
29736
29890
|
}
|
|
29737
29891
|
}
|
|
29738
29892
|
|
|
@@ -30146,6 +30300,12 @@ const TABLE_ELEMENTS_BY_PRIORITY = [
|
|
|
30146
30300
|
"headerRow",
|
|
30147
30301
|
"totalRow",
|
|
30148
30302
|
];
|
|
30303
|
+
/** Return the content zone of the table, ie. the table zone without the headers */
|
|
30304
|
+
function getTableContentZone(tableZone, tableConfig) {
|
|
30305
|
+
const numberOfHeaders = tableConfig.numberOfHeaders;
|
|
30306
|
+
const contentZone = { ...tableZone, top: tableZone.top + numberOfHeaders };
|
|
30307
|
+
return contentZone.top <= contentZone.bottom ? contentZone : undefined;
|
|
30308
|
+
}
|
|
30149
30309
|
function getComputedTableStyle(tableConfig, numberOfCols, numberOfRows) {
|
|
30150
30310
|
return {
|
|
30151
30311
|
borders: getAllTableBorders(tableConfig, numberOfCols, numberOfRows),
|
|
@@ -30597,14 +30757,6 @@ class TablePanel extends Component {
|
|
|
30597
30757
|
tableXc: this.env.model.getters.getRangeString(this.props.table.range, sheetId),
|
|
30598
30758
|
filtersEnabledIfPossible: this.props.table.config.hasFilters,
|
|
30599
30759
|
});
|
|
30600
|
-
onWillUpdateProps((nextProps) => {
|
|
30601
|
-
if (this.props.table.id !== nextProps.table.id) {
|
|
30602
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
30603
|
-
this.state.tableXc = this.env.model.getters.getRangeString(nextProps.table.range, sheetId);
|
|
30604
|
-
this.state.tableZoneErrors = [];
|
|
30605
|
-
this.state.filtersEnabledIfPossible = nextProps.table.config.hasFilters;
|
|
30606
|
-
}
|
|
30607
|
-
});
|
|
30608
30760
|
}
|
|
30609
30761
|
updateHasFilters(hasFilters) {
|
|
30610
30762
|
this.state.filtersEnabledIfPossible = hasFilters;
|
|
@@ -30753,7 +30905,11 @@ sidePanelRegistry.add("TableSidePanel", {
|
|
|
30753
30905
|
if (!table) {
|
|
30754
30906
|
return { isOpen: false };
|
|
30755
30907
|
}
|
|
30756
|
-
return {
|
|
30908
|
+
return {
|
|
30909
|
+
isOpen: true,
|
|
30910
|
+
props: { table },
|
|
30911
|
+
key: table.id,
|
|
30912
|
+
};
|
|
30757
30913
|
},
|
|
30758
30914
|
});
|
|
30759
30915
|
|
|
@@ -32468,19 +32624,21 @@ class GridCellIcon extends Component {
|
|
|
32468
32624
|
slots: Object,
|
|
32469
32625
|
};
|
|
32470
32626
|
get iconStyle() {
|
|
32471
|
-
const
|
|
32472
|
-
const
|
|
32627
|
+
const cellPosition = this.props.cellPosition;
|
|
32628
|
+
const merge = this.env.model.getters.getMerge(cellPosition);
|
|
32629
|
+
const zone = merge || positionToZone(cellPosition);
|
|
32630
|
+
const rect = this.env.model.getters.getVisibleRectWithoutHeaders(zone);
|
|
32631
|
+
const x = this.getIconHorizontalPosition(rect, cellPosition);
|
|
32632
|
+
const y = this.getIconVerticalPosition(rect, cellPosition);
|
|
32473
32633
|
return cssPropertiesToCss({
|
|
32474
32634
|
top: `${y + (this.props.offset?.y || 0)}px`,
|
|
32475
32635
|
left: `${x + (this.props.offset?.x || 0)}px`,
|
|
32476
32636
|
});
|
|
32477
32637
|
}
|
|
32478
|
-
getIconVerticalPosition() {
|
|
32479
|
-
const
|
|
32480
|
-
const
|
|
32481
|
-
const
|
|
32482
|
-
const end = this.env.model.getters.getRowDimensionsInViewport(sheetId, merge ? merge.bottom : row).end;
|
|
32483
|
-
const cell = this.env.model.getters.getCell(this.props.cellPosition);
|
|
32638
|
+
getIconVerticalPosition(rect, cellPosition) {
|
|
32639
|
+
const start = rect.y;
|
|
32640
|
+
const end = rect.y + rect.height;
|
|
32641
|
+
const cell = this.env.model.getters.getCell(cellPosition);
|
|
32484
32642
|
const align = this.props.verticalAlign || cell?.style?.verticalAlign || DEFAULT_VERTICAL_ALIGN;
|
|
32485
32643
|
switch (align) {
|
|
32486
32644
|
case "bottom":
|
|
@@ -32492,13 +32650,11 @@ class GridCellIcon extends Component {
|
|
|
32492
32650
|
return end - GRID_ICON_EDGE_LENGTH - centeringOffset;
|
|
32493
32651
|
}
|
|
32494
32652
|
}
|
|
32495
|
-
getIconHorizontalPosition() {
|
|
32496
|
-
const
|
|
32497
|
-
const
|
|
32498
|
-
const
|
|
32499
|
-
const
|
|
32500
|
-
const cell = this.env.model.getters.getCell(this.props.cellPosition);
|
|
32501
|
-
const evaluatedCell = this.env.model.getters.getEvaluatedCell(this.props.cellPosition);
|
|
32653
|
+
getIconHorizontalPosition(rect, cellPosition) {
|
|
32654
|
+
const start = rect.x;
|
|
32655
|
+
const end = rect.x + rect.width;
|
|
32656
|
+
const cell = this.env.model.getters.getCell(cellPosition);
|
|
32657
|
+
const evaluatedCell = this.env.model.getters.getEvaluatedCell(cellPosition);
|
|
32502
32658
|
const align = this.props.horizontalAlign || cell?.style?.align || evaluatedCell.defaultAlign;
|
|
32503
32659
|
switch (align) {
|
|
32504
32660
|
case "right":
|
|
@@ -32603,6 +32759,8 @@ css /* scss */ `
|
|
|
32603
32759
|
height: ${CHECKBOX_WIDTH}px;
|
|
32604
32760
|
accent-color: #808080;
|
|
32605
32761
|
margin: ${MARGIN}px;
|
|
32762
|
+
/** required to prevent the checkbox position to be sensible to the font-size (affects Firefox) */
|
|
32763
|
+
position: absolute;
|
|
32606
32764
|
}
|
|
32607
32765
|
`;
|
|
32608
32766
|
class DataValidationCheckbox extends Component {
|
|
@@ -32621,7 +32779,7 @@ class DataValidationCheckbox extends Component {
|
|
|
32621
32779
|
}
|
|
32622
32780
|
get isDisabled() {
|
|
32623
32781
|
const cell = this.env.model.getters.getCell(this.props.cellPosition);
|
|
32624
|
-
return !!cell?.isFormula;
|
|
32782
|
+
return this.env.model.getters.isReadonly() || !!cell?.isFormula;
|
|
32625
32783
|
}
|
|
32626
32784
|
}
|
|
32627
32785
|
|
|
@@ -32661,12 +32819,17 @@ class DataValidationOverlay extends Component {
|
|
|
32661
32819
|
static props = {};
|
|
32662
32820
|
static components = { GridCellIcon, DataValidationCheckbox, DataValidationListIcon };
|
|
32663
32821
|
get checkBoxCellPositions() {
|
|
32664
|
-
return this.env.model.getters
|
|
32822
|
+
return this.env.model.getters
|
|
32823
|
+
.getVisibleCellPositions()
|
|
32824
|
+
.filter(this.env.model.getters.isCellValidCheckbox);
|
|
32665
32825
|
}
|
|
32666
32826
|
get listIconsCellPositions() {
|
|
32667
|
-
|
|
32668
|
-
|
|
32669
|
-
|
|
32827
|
+
if (this.env.model.getters.isReadonly()) {
|
|
32828
|
+
return [];
|
|
32829
|
+
}
|
|
32830
|
+
return this.env.model.getters
|
|
32831
|
+
.getVisibleCellPositions()
|
|
32832
|
+
.filter(this.env.model.getters.cellHasListDataValidationIcon);
|
|
32670
32833
|
}
|
|
32671
32834
|
}
|
|
32672
32835
|
|
|
@@ -32711,7 +32874,7 @@ function dragFigureForMove({ x: mouseX, y: mouseY }, { x: mouseInitialX, y: mous
|
|
|
32711
32874
|
const newY = clip(initialFigure.y + deltaY, minY, maxY - initialFigure.height - scrollY);
|
|
32712
32875
|
return { ...initialFigure, x: newX, y: newY };
|
|
32713
32876
|
}
|
|
32714
|
-
function dragFigureForResize(initialFigure, dirX, dirY, { x: mouseX, y: mouseY }, { x: mouseInitialX, y: mouseInitialY }, keepRatio, minFigSize) {
|
|
32877
|
+
function dragFigureForResize(initialFigure, dirX, dirY, { x: mouseX, y: mouseY }, { x: mouseInitialX, y: mouseInitialY }, keepRatio, minFigSize, { scrollX, scrollY }) {
|
|
32715
32878
|
let { x, y, width, height } = initialFigure;
|
|
32716
32879
|
if (keepRatio && dirX != 0 && dirY != 0) {
|
|
32717
32880
|
const deltaX = Math.min(dirX * (mouseInitialX - mouseX), initialFigure.width - minFigSize);
|
|
@@ -32738,14 +32901,14 @@ function dragFigureForResize(initialFigure, dirX, dirY, { x: mouseX, y: mouseY }
|
|
|
32738
32901
|
y = initialFigure.y - deltaY;
|
|
32739
32902
|
}
|
|
32740
32903
|
}
|
|
32741
|
-
//
|
|
32742
|
-
if (x
|
|
32743
|
-
width
|
|
32744
|
-
x =
|
|
32904
|
+
// Adjusts figure dimensions to ensure it remains within header boundaries and viewport during resizing.
|
|
32905
|
+
if (x + scrollX <= 0) {
|
|
32906
|
+
width = width + x + scrollX;
|
|
32907
|
+
x = -scrollX;
|
|
32745
32908
|
}
|
|
32746
|
-
if (y
|
|
32747
|
-
height
|
|
32748
|
-
y =
|
|
32909
|
+
if (y + scrollY <= 0) {
|
|
32910
|
+
height = height + y + scrollY;
|
|
32911
|
+
y = -scrollY;
|
|
32749
32912
|
}
|
|
32750
32913
|
return { ...initialFigure, x, y, width, height };
|
|
32751
32914
|
}
|
|
@@ -33165,7 +33328,7 @@ class FiguresContainer extends Component {
|
|
|
33165
33328
|
const minFigSize = figureRegistry.get(figure.tag).minFigSize || MIN_FIG_SIZE;
|
|
33166
33329
|
const onMouseMove = (ev) => {
|
|
33167
33330
|
const currentMousePosition = { x: ev.clientX, y: ev.clientY };
|
|
33168
|
-
const draggedFigure = dragFigureForResize(initialFig, dirX, dirY, currentMousePosition, initialMousePosition, keepRatio, minFigSize);
|
|
33331
|
+
const draggedFigure = dragFigureForResize(initialFig, dirX, dirY, currentMousePosition, initialMousePosition, keepRatio, minFigSize, this.env.model.getters.getActiveSheetScrollInfo());
|
|
33169
33332
|
const otherFigures = this.getOtherFigures(figure.id);
|
|
33170
33333
|
const snapResult = snapForResize(this.env.model.getters, dirX, dirY, draggedFigure, otherFigures);
|
|
33171
33334
|
this.dnd.draggedFigure = snapResult.snappedFigure;
|
|
@@ -33341,29 +33504,6 @@ class GridAddRowsFooter extends Component {
|
|
|
33341
33504
|
}
|
|
33342
33505
|
}
|
|
33343
33506
|
|
|
33344
|
-
/**
|
|
33345
|
-
* Repeatedly calls a callback function with a time delay between calls.
|
|
33346
|
-
*/
|
|
33347
|
-
function useInterval(callback, delay) {
|
|
33348
|
-
let intervalId;
|
|
33349
|
-
const { setInterval, clearInterval } = window;
|
|
33350
|
-
useEffect(() => {
|
|
33351
|
-
intervalId = setInterval(callback, delay);
|
|
33352
|
-
return () => clearInterval(intervalId);
|
|
33353
|
-
}, () => [delay]);
|
|
33354
|
-
return {
|
|
33355
|
-
pause: () => {
|
|
33356
|
-
clearInterval(intervalId);
|
|
33357
|
-
intervalId = undefined;
|
|
33358
|
-
},
|
|
33359
|
-
resume: () => {
|
|
33360
|
-
if (intervalId === undefined) {
|
|
33361
|
-
intervalId = setInterval(callback, delay);
|
|
33362
|
-
}
|
|
33363
|
-
},
|
|
33364
|
-
};
|
|
33365
|
-
}
|
|
33366
|
-
|
|
33367
33507
|
const CURSOR_SVG = /*xml*/ `
|
|
33368
33508
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14" height="16"><path d="M6.5.4c1.3-.8 2.9-.1 3.8 1.4l2.9 5.1c.2.4.9 1.6-.4 2.3l-1.6.9 1.8 3.1c.2.4.1 1-.2 1.2l-1.6 1c-.3.1-.9 0-1.1-.4l-1.8-3.1-1.6 1c-.6.4-1.7 0-2.2-.8L0 4.3"/><path fill="#fff" d="M9.1 2a1.4 1.1 60 0 0-1.7-.6L5.5 2.5l.9 1.6-1 .6-.9-1.6-.6.4 1.8 3.1-1.3.7-1.8-3.1-1 .6 3.8 6.6 6.8-3.98M3.9 8.8 10.82 5l.795 1.4-6.81 3.96"/></svg>
|
|
33369
33509
|
`;
|
|
@@ -35248,10 +35388,17 @@ class SidePanelStore extends SpreadsheetStore {
|
|
|
35248
35388
|
get panelProps() {
|
|
35249
35389
|
const state = this.computeState(this.componentTag, this.initialPanelProps);
|
|
35250
35390
|
if (state.isOpen) {
|
|
35251
|
-
return state.props;
|
|
35391
|
+
return state.props ?? {};
|
|
35252
35392
|
}
|
|
35253
35393
|
return {};
|
|
35254
35394
|
}
|
|
35395
|
+
get panelKey() {
|
|
35396
|
+
const state = this.computeState(this.componentTag, this.initialPanelProps);
|
|
35397
|
+
if (state.isOpen) {
|
|
35398
|
+
return state.key;
|
|
35399
|
+
}
|
|
35400
|
+
return undefined;
|
|
35401
|
+
}
|
|
35255
35402
|
open(componentTag, panelProps = {}) {
|
|
35256
35403
|
const state = this.computeState(componentTag, panelProps);
|
|
35257
35404
|
if (state.isOpen === false) {
|
|
@@ -35261,7 +35408,7 @@ class SidePanelStore extends SpreadsheetStore {
|
|
|
35261
35408
|
this.initialPanelProps?.onCloseSidePanel?.();
|
|
35262
35409
|
}
|
|
35263
35410
|
this.componentTag = componentTag;
|
|
35264
|
-
this.initialPanelProps = state.props;
|
|
35411
|
+
this.initialPanelProps = state.props ?? {};
|
|
35265
35412
|
}
|
|
35266
35413
|
toggle(componentTag, panelProps) {
|
|
35267
35414
|
if (this.isOpen && componentTag === this.componentTag) {
|
|
@@ -40738,10 +40885,8 @@ function compileTokens(tokens) {
|
|
|
40738
40885
|
"ref", // a function to access a certain dependency at a given index
|
|
40739
40886
|
"range", // same as above, but guarantee that the result is in the form of a range
|
|
40740
40887
|
"ctx", code.toString());
|
|
40741
|
-
|
|
40742
|
-
|
|
40743
|
-
execute: baseFunction,
|
|
40744
|
-
};
|
|
40888
|
+
// @ts-ignore
|
|
40889
|
+
functionCache[cacheKey] = baseFunction;
|
|
40745
40890
|
/**
|
|
40746
40891
|
* This function compile the function arguments. It is mostly straightforward,
|
|
40747
40892
|
* except that there is a non trivial transformation in one situation:
|
|
@@ -40848,7 +40993,7 @@ function compileTokens(tokens) {
|
|
|
40848
40993
|
}
|
|
40849
40994
|
}
|
|
40850
40995
|
const compiledFormula = {
|
|
40851
|
-
execute: functionCache[cacheKey]
|
|
40996
|
+
execute: functionCache[cacheKey],
|
|
40852
40997
|
dependencies,
|
|
40853
40998
|
constantValues,
|
|
40854
40999
|
tokens,
|
|
@@ -42333,6 +42478,15 @@ class FigurePlugin extends CorePlugin {
|
|
|
42333
42478
|
return "Success" /* CommandResult.Success */;
|
|
42334
42479
|
}
|
|
42335
42480
|
}
|
|
42481
|
+
beforeHandle(cmd) {
|
|
42482
|
+
switch (cmd.type) {
|
|
42483
|
+
case "DELETE_SHEET":
|
|
42484
|
+
this.getters.getFigures(cmd.sheetId).forEach((figure) => {
|
|
42485
|
+
this.dispatch("DELETE_FIGURE", { id: figure.id, sheetId: cmd.sheetId });
|
|
42486
|
+
});
|
|
42487
|
+
break;
|
|
42488
|
+
}
|
|
42489
|
+
}
|
|
42336
42490
|
handle(cmd) {
|
|
42337
42491
|
switch (cmd.type) {
|
|
42338
42492
|
case "CREATE_SHEET":
|
|
@@ -43819,7 +43973,6 @@ class SheetPlugin extends CorePlugin {
|
|
|
43819
43973
|
"getNumberHeaders",
|
|
43820
43974
|
"getGridLinesVisibility",
|
|
43821
43975
|
"getNextSheetName",
|
|
43822
|
-
"isEmpty",
|
|
43823
43976
|
"getSheetSize",
|
|
43824
43977
|
"getSheetZone",
|
|
43825
43978
|
"getPaneDivisions",
|
|
@@ -44191,14 +44344,6 @@ class SheetPlugin extends CorePlugin {
|
|
|
44191
44344
|
// ---------------------------------------------------------------------------
|
|
44192
44345
|
// Row/Col manipulation
|
|
44193
44346
|
// ---------------------------------------------------------------------------
|
|
44194
|
-
/**
|
|
44195
|
-
* Check if a zone only contains empty cells
|
|
44196
|
-
*/
|
|
44197
|
-
isEmpty(sheetId, zone) {
|
|
44198
|
-
return positions(zone)
|
|
44199
|
-
.map(({ col, row }) => this.getCell({ sheetId, col, row }))
|
|
44200
|
-
.every((cell) => !cell || cell.content === "");
|
|
44201
|
-
}
|
|
44202
44347
|
getCommandZones(cmd) {
|
|
44203
44348
|
const zones = [];
|
|
44204
44349
|
if ("zone" in cmd) {
|
|
@@ -45002,13 +45147,15 @@ class TablePlugin extends CorePlugin {
|
|
|
45002
45147
|
if (zone.left !== zone.right) {
|
|
45003
45148
|
throw new Error("Can only define a filter on a single column");
|
|
45004
45149
|
}
|
|
45005
|
-
const
|
|
45006
|
-
const filteredRange =
|
|
45150
|
+
const contentZone = getTableContentZone(zone, config);
|
|
45151
|
+
const filteredRange = contentZone
|
|
45152
|
+
? this.getters.getRangeFromZone(range.sheetId, contentZone)
|
|
45153
|
+
: undefined;
|
|
45007
45154
|
return {
|
|
45008
45155
|
id,
|
|
45009
45156
|
rangeWithHeaders: range,
|
|
45010
45157
|
col: zone.left,
|
|
45011
|
-
filteredRange
|
|
45158
|
+
filteredRange,
|
|
45012
45159
|
};
|
|
45013
45160
|
}
|
|
45014
45161
|
copyTableForSheet(sheetId, table) {
|
|
@@ -45617,7 +45764,11 @@ class CompilationParametersBuilder {
|
|
|
45617
45764
|
});
|
|
45618
45765
|
}
|
|
45619
45766
|
getParameters() {
|
|
45620
|
-
return
|
|
45767
|
+
return {
|
|
45768
|
+
referenceDenormalizer: this.refFn.bind(this),
|
|
45769
|
+
ensureRange: this.range.bind(this),
|
|
45770
|
+
evalContext: this.evalContext,
|
|
45771
|
+
};
|
|
45621
45772
|
}
|
|
45622
45773
|
/**
|
|
45623
45774
|
* Returns the value of the cell(s) used in reference
|
|
@@ -46564,7 +46715,6 @@ const EMPTY_ARRAY = [];
|
|
|
46564
46715
|
const MAX_ITERATION = 30;
|
|
46565
46716
|
const ERROR_CYCLE_CELL = createEvaluatedCell(new CircularDependencyError());
|
|
46566
46717
|
const EMPTY_CELL = createEvaluatedCell({ value: null });
|
|
46567
|
-
const EVAL_CONTEXT_INDEX = 2;
|
|
46568
46718
|
class Evaluator {
|
|
46569
46719
|
context;
|
|
46570
46720
|
getters;
|
|
@@ -46617,9 +46767,8 @@ class Evaluator {
|
|
|
46617
46767
|
updateCompilationParameters() {
|
|
46618
46768
|
// rebuild the compilation parameters (with a clean cache)
|
|
46619
46769
|
this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
|
|
46620
|
-
this.compilationParams
|
|
46621
|
-
|
|
46622
|
-
this.compilationParams[EVAL_CONTEXT_INDEX].addDependencies = this.addDependencies.bind(this);
|
|
46770
|
+
this.compilationParams.evalContext.updateDependencies = this.updateDependencies.bind(this);
|
|
46771
|
+
this.compilationParams.evalContext.addDependencies = this.addDependencies.bind(this);
|
|
46623
46772
|
}
|
|
46624
46773
|
evaluateCells(positions) {
|
|
46625
46774
|
const cells = positions.map((p) => this.encoder.encode(p));
|
|
@@ -46744,6 +46893,8 @@ class Evaluator {
|
|
|
46744
46893
|
: evaluateLiteral(cell.content, localeFormat);
|
|
46745
46894
|
}
|
|
46746
46895
|
catch (e) {
|
|
46896
|
+
e.value = e?.value || CellErrorType.GenericError;
|
|
46897
|
+
e.message = e?.message || implementationErrorMessage;
|
|
46747
46898
|
return createEvaluatedCell(e);
|
|
46748
46899
|
}
|
|
46749
46900
|
finally {
|
|
@@ -46966,16 +47117,16 @@ class PositionBitsEncoder {
|
|
|
46966
47117
|
}
|
|
46967
47118
|
}
|
|
46968
47119
|
function updateEvalContextAndExecute(compiledFormula, compilationParams, sheetId, cellId) {
|
|
46969
|
-
compilationParams
|
|
47120
|
+
compilationParams.evalContext.__originCellXC = lazy(() => {
|
|
46970
47121
|
if (!cellId) {
|
|
46971
47122
|
return undefined;
|
|
46972
47123
|
}
|
|
46973
47124
|
// compute the value lazily for performance reasons
|
|
46974
|
-
const position = compilationParams
|
|
47125
|
+
const position = compilationParams.evalContext.getters.getCellPosition(cellId);
|
|
46975
47126
|
return toXC(position.col, position.row);
|
|
46976
47127
|
});
|
|
46977
|
-
compilationParams
|
|
46978
|
-
return compiledFormula.execute(compiledFormula.dependencies,
|
|
47128
|
+
compilationParams.evalContext.__originSheetId = sheetId;
|
|
47129
|
+
return compiledFormula.execute(compiledFormula.dependencies, compilationParams.referenceDenormalizer, compilationParams.ensureRange, compilationParams.evalContext);
|
|
46979
47130
|
}
|
|
46980
47131
|
|
|
46981
47132
|
//#region
|
|
@@ -47082,6 +47233,7 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
47082
47233
|
"getEvaluatedCellsInZone",
|
|
47083
47234
|
"getSpreadPositionsOf",
|
|
47084
47235
|
"getArrayFormulaSpreadingOn",
|
|
47236
|
+
"isEmpty",
|
|
47085
47237
|
];
|
|
47086
47238
|
shouldRebuildDependenciesGraph = true;
|
|
47087
47239
|
evaluator;
|
|
@@ -47187,6 +47339,14 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
47187
47339
|
getArrayFormulaSpreadingOn(position) {
|
|
47188
47340
|
return this.evaluator.getArrayFormulaSpreadingOn(position);
|
|
47189
47341
|
}
|
|
47342
|
+
/**
|
|
47343
|
+
* Check if a zone only contains empty cells
|
|
47344
|
+
*/
|
|
47345
|
+
isEmpty(sheetId, zone) {
|
|
47346
|
+
return positions(zone)
|
|
47347
|
+
.map(({ col, row }) => this.getEvaluatedCell({ sheetId, col, row }))
|
|
47348
|
+
.every((cell) => cell.type === CellValueType.empty);
|
|
47349
|
+
}
|
|
47190
47350
|
// ---------------------------------------------------------------------------
|
|
47191
47351
|
// Export
|
|
47192
47352
|
// ---------------------------------------------------------------------------
|
|
@@ -47304,12 +47464,13 @@ function colorDistance(color1, color2) {
|
|
|
47304
47464
|
*/
|
|
47305
47465
|
class CustomColorsPlugin extends UIPlugin {
|
|
47306
47466
|
customColors = {};
|
|
47307
|
-
|
|
47308
|
-
shouldUpdateColors = false;
|
|
47467
|
+
shouldUpdateColors = true;
|
|
47309
47468
|
static getters = ["getCustomColors"];
|
|
47310
47469
|
constructor(config) {
|
|
47311
47470
|
super(config);
|
|
47312
|
-
|
|
47471
|
+
for (const color of config.customColors ?? []) {
|
|
47472
|
+
this.tryToAddColor(color);
|
|
47473
|
+
}
|
|
47313
47474
|
}
|
|
47314
47475
|
handle(cmd) {
|
|
47315
47476
|
switch (cmd.type) {
|
|
@@ -47320,31 +47481,29 @@ class CustomColorsPlugin extends UIPlugin {
|
|
|
47320
47481
|
case "SET_BORDER":
|
|
47321
47482
|
case "SET_ZONE_BORDERS":
|
|
47322
47483
|
case "SET_FORMATTING":
|
|
47484
|
+
case "CREATE_TABLE":
|
|
47485
|
+
case "UPDATE_TABLE":
|
|
47323
47486
|
this.history.update("shouldUpdateColors", true);
|
|
47487
|
+
break;
|
|
47324
47488
|
}
|
|
47325
47489
|
}
|
|
47326
47490
|
finalize() {
|
|
47327
47491
|
if (this.shouldUpdateColors) {
|
|
47328
47492
|
this.history.update("shouldUpdateColors", false);
|
|
47329
|
-
for (const color of this.
|
|
47493
|
+
for (const color of this.computeCustomColors()) {
|
|
47330
47494
|
this.tryToAddColor(color);
|
|
47331
47495
|
}
|
|
47332
47496
|
}
|
|
47333
47497
|
}
|
|
47334
47498
|
getCustomColors() {
|
|
47335
|
-
|
|
47499
|
+
return sortWithClusters(Object.keys(this.customColors));
|
|
47500
|
+
}
|
|
47501
|
+
computeCustomColors() {
|
|
47502
|
+
let usedColors = [];
|
|
47336
47503
|
for (const sheetId of this.getters.getSheetIds()) {
|
|
47337
|
-
usedColors = usedColors.concat(this.getColorsFromCells(sheetId), this.getFormattingColors(sheetId), this.getChartColors(sheetId));
|
|
47338
|
-
}
|
|
47339
|
-
return
|
|
47340
|
-
...new Set(
|
|
47341
|
-
// remove duplicates first to check validity on a reduced
|
|
47342
|
-
// set of colors, then normalize to HEX and remove duplicates
|
|
47343
|
-
// again
|
|
47344
|
-
[...new Set([...usedColors, ...Object.keys(this.customColors)])]
|
|
47345
|
-
.filter(isColorValid)
|
|
47346
|
-
.map(toHex)),
|
|
47347
|
-
]).filter((color) => !COLOR_PICKER_DEFAULTS.includes(color));
|
|
47504
|
+
usedColors = usedColors.concat(this.getColorsFromCells(sheetId), this.getFormattingColors(sheetId), this.getChartColors(sheetId), this.getTableColors(sheetId));
|
|
47505
|
+
}
|
|
47506
|
+
return [...new Set([...usedColors])];
|
|
47348
47507
|
}
|
|
47349
47508
|
getColorsFromCells(sheetId) {
|
|
47350
47509
|
const cells = Object.values(this.getters.getCells(sheetId));
|
|
@@ -47406,7 +47565,43 @@ class CustomColorsPlugin extends UIPlugin {
|
|
|
47406
47565
|
}
|
|
47407
47566
|
return [...chartsColors];
|
|
47408
47567
|
}
|
|
47568
|
+
getTableColors(sheetId) {
|
|
47569
|
+
const tables = this.getters.getTables(sheetId);
|
|
47570
|
+
return tables.flatMap((table) => {
|
|
47571
|
+
const config = table.config;
|
|
47572
|
+
const style = TABLE_PRESETS[config.styleId];
|
|
47573
|
+
return [
|
|
47574
|
+
this.getTableStyleElementColors(style.wholeTable),
|
|
47575
|
+
config.numberOfHeaders > 0 ? this.getTableStyleElementColors(style.headerRow) : [],
|
|
47576
|
+
config.totalRow ? this.getTableStyleElementColors(style.totalRow) : [],
|
|
47577
|
+
config.bandedColumns ? this.getTableStyleElementColors(style.firstColumnStripe) : [],
|
|
47578
|
+
config.bandedColumns ? this.getTableStyleElementColors(style.secondColumnStripe) : [],
|
|
47579
|
+
config.bandedRows ? this.getTableStyleElementColors(style.firstRowStripe) : [],
|
|
47580
|
+
config.bandedRows ? this.getTableStyleElementColors(style.secondRowStripe) : [],
|
|
47581
|
+
config.firstColumn ? this.getTableStyleElementColors(style.firstColumn) : [],
|
|
47582
|
+
config.lastColumn ? this.getTableStyleElementColors(style.lastColumn) : [],
|
|
47583
|
+
].flat();
|
|
47584
|
+
});
|
|
47585
|
+
}
|
|
47586
|
+
getTableStyleElementColors(element) {
|
|
47587
|
+
if (!element) {
|
|
47588
|
+
return [];
|
|
47589
|
+
}
|
|
47590
|
+
return [
|
|
47591
|
+
element.style?.fillColor,
|
|
47592
|
+
element.style?.textColor,
|
|
47593
|
+
element.border?.bottom?.color,
|
|
47594
|
+
element.border?.top?.color,
|
|
47595
|
+
element.border?.left?.color,
|
|
47596
|
+
element.border?.right?.color,
|
|
47597
|
+
element.border?.horizontal?.color,
|
|
47598
|
+
element.border?.vertical?.color,
|
|
47599
|
+
].filter(isDefined$1);
|
|
47600
|
+
}
|
|
47409
47601
|
tryToAddColor(color) {
|
|
47602
|
+
if (!isColorValid(color)) {
|
|
47603
|
+
return;
|
|
47604
|
+
}
|
|
47410
47605
|
const formattedColor = toHex(color);
|
|
47411
47606
|
if (color && !COLOR_PICKER_DEFAULTS.includes(formattedColor)) {
|
|
47412
47607
|
this.history.update("customColors", formattedColor, true);
|
|
@@ -47830,8 +48025,6 @@ const VALID_RESULT = { isValid: true };
|
|
|
47830
48025
|
class EvaluationDataValidationPlugin extends UIPlugin {
|
|
47831
48026
|
static getters = [
|
|
47832
48027
|
"getDataValidationInvalidCriterionValueMessage",
|
|
47833
|
-
"getDataValidationCheckBoxCellPositions",
|
|
47834
|
-
"getDataValidationListCellsPositions",
|
|
47835
48028
|
"getInvalidDataValidationMessage",
|
|
47836
48029
|
"getValidationResultForCellValue",
|
|
47837
48030
|
"isCellValidCheckbox",
|
|
@@ -47909,19 +48102,6 @@ class EvaluationDataValidationPlugin extends UIPlugin {
|
|
|
47909
48102
|
const error = this.getRuleErrorForCellValue(cellValue, cellPosition, rule);
|
|
47910
48103
|
return error ? { error, rule, isValid: false } : VALID_RESULT;
|
|
47911
48104
|
}
|
|
47912
|
-
getDataValidationCheckBoxCellPositions() {
|
|
47913
|
-
const rules = this.getters
|
|
47914
|
-
.getDataValidationRules(this.getters.getActiveSheetId())
|
|
47915
|
-
.filter((rule) => rule.criterion.type === "isBoolean");
|
|
47916
|
-
return getCellPositionsInRanges(rules.map((rule) => rule.ranges).flat()).filter((position) => this.isCellValidCheckbox(position));
|
|
47917
|
-
}
|
|
47918
|
-
getDataValidationListCellsPositions() {
|
|
47919
|
-
const rules = this.getters
|
|
47920
|
-
.getDataValidationRules(this.getters.getActiveSheetId())
|
|
47921
|
-
.filter((rule) => (rule.criterion.type === "isValueInList" || rule.criterion.type === "isValueInRange") &&
|
|
47922
|
-
rule.criterion.displayStyle === "arrow");
|
|
47923
|
-
return getCellPositionsInRanges(rules.map((rule) => rule.ranges).flat());
|
|
47924
|
-
}
|
|
47925
48105
|
getValidationResultForCell(cellPosition) {
|
|
47926
48106
|
const { col, row, sheetId } = cellPosition;
|
|
47927
48107
|
if (!this.validationResults[sheetId]) {
|
|
@@ -48378,6 +48558,23 @@ class AutofillPlugin extends UIPlugin {
|
|
|
48378
48558
|
* autofiller
|
|
48379
48559
|
*/
|
|
48380
48560
|
autofillAuto() {
|
|
48561
|
+
const activePosition = this.getters.getActivePosition();
|
|
48562
|
+
const table = this.getters.getTable(activePosition);
|
|
48563
|
+
let autofillRow = table ? table.range.zone.bottom : this.getAutofillAutoLastRow();
|
|
48564
|
+
// Stop autofill at the next non-empty cell
|
|
48565
|
+
const selection = this.getters.getSelectedZone();
|
|
48566
|
+
for (let row = selection.bottom + 1; row <= autofillRow; row++) {
|
|
48567
|
+
if (this.getters.getEvaluatedCell({ ...activePosition, row }).type !== CellValueType.empty) {
|
|
48568
|
+
autofillRow = row - 1;
|
|
48569
|
+
break;
|
|
48570
|
+
}
|
|
48571
|
+
}
|
|
48572
|
+
if (autofillRow > selection.bottom) {
|
|
48573
|
+
this.select(activePosition.col, autofillRow);
|
|
48574
|
+
this.autofill(true);
|
|
48575
|
+
}
|
|
48576
|
+
}
|
|
48577
|
+
getAutofillAutoLastRow() {
|
|
48381
48578
|
const zone = this.getters.getSelectedZone();
|
|
48382
48579
|
const sheetId = this.getters.getActiveSheetId();
|
|
48383
48580
|
let col = zone.left;
|
|
@@ -48401,10 +48598,7 @@ class AutofillPlugin extends UIPlugin {
|
|
|
48401
48598
|
}
|
|
48402
48599
|
}
|
|
48403
48600
|
}
|
|
48404
|
-
|
|
48405
|
-
this.select(zone.left, row - 1);
|
|
48406
|
-
this.autofill(true);
|
|
48407
|
-
}
|
|
48601
|
+
return row - 1;
|
|
48408
48602
|
}
|
|
48409
48603
|
/**
|
|
48410
48604
|
* Generate the next cell
|
|
@@ -49946,7 +50140,6 @@ class DataCleanupPlugin extends UIPlugin {
|
|
|
49946
50140
|
* the search with a new value.
|
|
49947
50141
|
*/
|
|
49948
50142
|
class FindAndReplacePlugin extends UIPlugin {
|
|
49949
|
-
static layers = ["Search"];
|
|
49950
50143
|
static getters = [];
|
|
49951
50144
|
handle(cmd) {
|
|
49952
50145
|
switch (cmd.type) {
|
|
@@ -51016,6 +51209,51 @@ class SplitToColumnsPlugin extends UIPlugin {
|
|
|
51016
51209
|
}
|
|
51017
51210
|
}
|
|
51018
51211
|
|
|
51212
|
+
class TableAutofillPlugin extends UIPlugin {
|
|
51213
|
+
handle(cmd) {
|
|
51214
|
+
switch (cmd.type) {
|
|
51215
|
+
case "AUTOFILL_TABLE_COLUMN":
|
|
51216
|
+
const table = this.getters.getTable(cmd);
|
|
51217
|
+
const cell = this.getters.getCell(cmd);
|
|
51218
|
+
if (!table || !table.config.automaticAutofill || !cell?.isFormula)
|
|
51219
|
+
return;
|
|
51220
|
+
const { col, row } = cmd;
|
|
51221
|
+
const tableContentZone = getTableContentZone(table.range.zone, table.config);
|
|
51222
|
+
if (tableContentZone && isInside(col, row, tableContentZone)) {
|
|
51223
|
+
this.autofillTableZone(cmd, tableContentZone);
|
|
51224
|
+
}
|
|
51225
|
+
break;
|
|
51226
|
+
}
|
|
51227
|
+
}
|
|
51228
|
+
autofillTableZone(autofillSource, zone) {
|
|
51229
|
+
if (zone.top === zone.bottom) {
|
|
51230
|
+
return;
|
|
51231
|
+
}
|
|
51232
|
+
const { col, row, sheetId } = autofillSource;
|
|
51233
|
+
for (let r = zone.top; r <= zone.bottom; r++) {
|
|
51234
|
+
if (r === row) {
|
|
51235
|
+
continue;
|
|
51236
|
+
}
|
|
51237
|
+
if (this.getters.getEvaluatedCell({ col, row: r, sheetId }).type !== CellValueType.empty) {
|
|
51238
|
+
return;
|
|
51239
|
+
}
|
|
51240
|
+
}
|
|
51241
|
+
// TODO: seems odd that autofill a table column have side effects on the selection. Autofill commands should be
|
|
51242
|
+
// refactored to take the selection as a parameter
|
|
51243
|
+
const oldSelection = {
|
|
51244
|
+
zone: this.getters.getSelectedZone(),
|
|
51245
|
+
cell: this.getters.getActivePosition(),
|
|
51246
|
+
};
|
|
51247
|
+
this.selection.selectCell(col, row);
|
|
51248
|
+
this.dispatch("AUTOFILL_SELECT", { col, row: zone.bottom });
|
|
51249
|
+
this.dispatch("AUTOFILL");
|
|
51250
|
+
this.selection.selectCell(col, row);
|
|
51251
|
+
this.dispatch("AUTOFILL_SELECT", { col, row: zone.top });
|
|
51252
|
+
this.dispatch("AUTOFILL");
|
|
51253
|
+
this.selection.selectZone(oldSelection);
|
|
51254
|
+
}
|
|
51255
|
+
}
|
|
51256
|
+
|
|
51019
51257
|
class TableStylePlugin extends UIPlugin {
|
|
51020
51258
|
static getters = ["getCellTableStyle", "getCellTableBorder"];
|
|
51021
51259
|
tableStyles = {};
|
|
@@ -52883,6 +53121,8 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
52883
53121
|
"getEdgeScrollRow",
|
|
52884
53122
|
"getVisibleFigures",
|
|
52885
53123
|
"getVisibleRect",
|
|
53124
|
+
"getVisibleRectWithoutHeaders",
|
|
53125
|
+
"getVisibleCellPositions",
|
|
52886
53126
|
"getColRowOffsetInViewport",
|
|
52887
53127
|
"getMainViewportCoordinates",
|
|
52888
53128
|
"getActiveSheetScrollInfo",
|
|
@@ -53128,6 +53368,26 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
53128
53368
|
const viewports = this.getSubViewports(sheetId);
|
|
53129
53369
|
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
53130
53370
|
}
|
|
53371
|
+
/**
|
|
53372
|
+
* Get the positions of all the cells that are visible in the viewport, taking merges into account.
|
|
53373
|
+
*/
|
|
53374
|
+
getVisibleCellPositions() {
|
|
53375
|
+
const visibleCols = this.getSheetViewVisibleCols();
|
|
53376
|
+
const visibleRows = this.getSheetViewVisibleRows();
|
|
53377
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
53378
|
+
const positions = [];
|
|
53379
|
+
for (const col of visibleCols) {
|
|
53380
|
+
for (const row of visibleRows) {
|
|
53381
|
+
const position = { sheetId, col, row };
|
|
53382
|
+
const mainPosition = this.getters.getMainCellPosition(position);
|
|
53383
|
+
if (mainPosition.row !== row || mainPosition.col !== col) {
|
|
53384
|
+
continue;
|
|
53385
|
+
}
|
|
53386
|
+
positions.push(position);
|
|
53387
|
+
}
|
|
53388
|
+
}
|
|
53389
|
+
return positions;
|
|
53390
|
+
}
|
|
53131
53391
|
/**
|
|
53132
53392
|
* Return the main viewport maximum size relative to the client size.
|
|
53133
53393
|
*/
|
|
@@ -53247,6 +53507,13 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
53247
53507
|
* Computes the coordinates and size to draw the zone on the canvas
|
|
53248
53508
|
*/
|
|
53249
53509
|
getVisibleRect(zone) {
|
|
53510
|
+
const rect = this.getVisibleRectWithoutHeaders(zone);
|
|
53511
|
+
return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
|
|
53512
|
+
}
|
|
53513
|
+
/**
|
|
53514
|
+
* Computes the coordinates and size to draw the zone without taking the grid offset into account
|
|
53515
|
+
*/
|
|
53516
|
+
getVisibleRectWithoutHeaders(zone) {
|
|
53250
53517
|
const sheetId = this.getters.getActiveSheetId();
|
|
53251
53518
|
const viewportRects = this.getSubViewports(sheetId)
|
|
53252
53519
|
.map((viewport) => viewport.getRect(zone))
|
|
@@ -53258,12 +53525,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
53258
53525
|
const y = Math.min(...viewportRects.map((rect) => rect.y));
|
|
53259
53526
|
const width = Math.max(...viewportRects.map((rect) => rect.x + rect.width)) - x;
|
|
53260
53527
|
const height = Math.max(...viewportRects.map((rect) => rect.y + rect.height)) - y;
|
|
53261
|
-
return {
|
|
53262
|
-
x: x + this.gridOffsetX,
|
|
53263
|
-
y: y + this.gridOffsetY,
|
|
53264
|
-
width,
|
|
53265
|
-
height,
|
|
53266
|
-
};
|
|
53528
|
+
return { x, y, width, height };
|
|
53267
53529
|
}
|
|
53268
53530
|
/**
|
|
53269
53531
|
* Returns the position of the MainViewport relatively to the start of the grid (without headers)
|
|
@@ -53517,13 +53779,8 @@ class HeaderPositionsUIPlugin extends UIPlugin {
|
|
|
53517
53779
|
}
|
|
53518
53780
|
break;
|
|
53519
53781
|
case "UPDATE_CELL":
|
|
53520
|
-
|
|
53521
|
-
|
|
53522
|
-
this.isDirty = true;
|
|
53523
|
-
}
|
|
53524
|
-
else {
|
|
53525
|
-
this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
|
|
53526
|
-
}
|
|
53782
|
+
this.headerPositions = {};
|
|
53783
|
+
this.isDirty = true;
|
|
53527
53784
|
break;
|
|
53528
53785
|
case "UPDATE_FILTER":
|
|
53529
53786
|
case "UPDATE_TABLE":
|
|
@@ -53646,7 +53903,8 @@ const featurePluginRegistry = new Registry()
|
|
|
53646
53903
|
.add("split_to_columns", SplitToColumnsPlugin)
|
|
53647
53904
|
.add("collaborative", CollaborativePlugin)
|
|
53648
53905
|
.add("history", HistoryPlugin)
|
|
53649
|
-
.add("data_cleanup", DataCleanupPlugin)
|
|
53906
|
+
.add("data_cleanup", DataCleanupPlugin)
|
|
53907
|
+
.add("table_autofill", TableAutofillPlugin);
|
|
53650
53908
|
// Plugins which have a state, but which should not be shared in collaborative
|
|
53651
53909
|
const statefulUIPluginRegistry = new Registry()
|
|
53652
53910
|
.add("selection", GridSelectionPlugin)
|
|
@@ -53989,6 +54247,9 @@ class BottomBarSheet extends Component {
|
|
|
53989
54247
|
this.scrollToSheet();
|
|
53990
54248
|
}
|
|
53991
54249
|
onDblClick() {
|
|
54250
|
+
if (this.env.model.getters.isReadonly()) {
|
|
54251
|
+
return;
|
|
54252
|
+
}
|
|
53992
54253
|
this.startEdition();
|
|
53993
54254
|
}
|
|
53994
54255
|
onKeyDown(ev) {
|
|
@@ -55945,7 +56206,6 @@ class Spreadsheet extends Component {
|
|
|
55945
56206
|
}
|
|
55946
56207
|
}, () => [this.env.model.getters.getActiveSheetId()]);
|
|
55947
56208
|
useExternalListener(window, "resize", () => this.render(true));
|
|
55948
|
-
useExternalListener(window, "beforeunload", this.unbindModelEvents.bind(this));
|
|
55949
56209
|
this.bindModelEvents();
|
|
55950
56210
|
onWillUpdateProps((nextProps) => {
|
|
55951
56211
|
if (nextProps.model !== this.props.model) {
|
|
@@ -59745,6 +60005,6 @@ const constants = {
|
|
|
59745
60005
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
59746
60006
|
|
|
59747
60007
|
|
|
59748
|
-
__info__.version = "17.2.0-alpha.
|
|
59749
|
-
__info__.date = "2024-
|
|
59750
|
-
__info__.hash = "
|
|
60008
|
+
__info__.version = "17.2.0-alpha.8";
|
|
60009
|
+
__info__.date = "2024-03-15T11:01:01.388Z";
|
|
60010
|
+
__info__.hash = "11cf381";
|