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