@odoo/o-spreadsheet 18.1.5 → 18.1.7
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 +209 -140
- package/dist/o-spreadsheet.d.ts +17 -15
- package/dist/o-spreadsheet.esm.js +209 -140
- package/dist/o-spreadsheet.iife.js +209 -140
- package/dist/o-spreadsheet.iife.min.js +9 -9
- package/dist/o_spreadsheet.xml +5 -4
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 18.1.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.1.7
|
|
6
|
+
* @date 2025-02-10T09:00:28.556Z
|
|
7
|
+
* @hash 338d8a1
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -768,9 +768,16 @@ function deepEqualsArray(arr1, arr2) {
|
|
|
768
768
|
}
|
|
769
769
|
return true;
|
|
770
770
|
}
|
|
771
|
-
/**
|
|
771
|
+
/**
|
|
772
|
+
* Check if the given array contains all the values of the other array.
|
|
773
|
+
* It makes the assumption that both array do not contain duplicates.
|
|
774
|
+
*/
|
|
772
775
|
function includesAll(arr, values) {
|
|
773
|
-
|
|
776
|
+
if (arr.length < values.length) {
|
|
777
|
+
return false;
|
|
778
|
+
}
|
|
779
|
+
const set = new Set(arr);
|
|
780
|
+
return values.every((value) => set.has(value));
|
|
774
781
|
}
|
|
775
782
|
/**
|
|
776
783
|
* Return an object with all the keys in the object that have a falsy value removed.
|
|
@@ -18454,19 +18461,20 @@ const HLOOKUP = {
|
|
|
18454
18461
|
description: _t("Horizontal lookup"),
|
|
18455
18462
|
args: [
|
|
18456
18463
|
arg("search_key (string, number, boolean)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18457
|
-
arg("range (range)", _t("The range to consider for the search. The first row in the range is searched for the key specified in search_key.")),
|
|
18464
|
+
arg("range (any, range)", _t("The range to consider for the search. The first row in the range is searched for the key specified in search_key.")),
|
|
18458
18465
|
arg("index (number)", _t("The row index of the value to be returned, where the first row in range is numbered 1.")),
|
|
18459
18466
|
arg(`is_sorted (boolean, default=${DEFAULT_IS_SORTED})`, _t("Indicates whether the row to be searched (the first row of the specified range) is sorted, in which case the closest match for search_key will be returned.")),
|
|
18460
18467
|
],
|
|
18461
18468
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18462
18469
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18463
|
-
|
|
18470
|
+
const _range = toMatrix(range);
|
|
18471
|
+
assert(() => 1 <= _index && _index <= _range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18464
18472
|
const getValueFromRange = (range, index) => range[index][0].value;
|
|
18465
18473
|
const _isSorted = toBoolean(isSorted.value);
|
|
18466
18474
|
const colIndex = _isSorted
|
|
18467
|
-
? dichotomicSearch(
|
|
18468
|
-
: linearSearch(
|
|
18469
|
-
const col =
|
|
18475
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range.length, getValueFromRange)
|
|
18476
|
+
: linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange);
|
|
18477
|
+
const col = _range[colIndex];
|
|
18470
18478
|
if (col === undefined) {
|
|
18471
18479
|
return valueNotAvailable(searchKey);
|
|
18472
18480
|
}
|
|
@@ -18558,35 +18566,37 @@ const LOOKUP = {
|
|
|
18558
18566
|
description: _t("Look up a value."),
|
|
18559
18567
|
args: [
|
|
18560
18568
|
arg("search_key (string, number, boolean)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18561
|
-
arg("search_array (range)", _t("One method of using this function is to provide a single sorted row or column search_array to look through for the search_key with a second argument result_range. The other way is to combine these two arguments into one search_array where the first row or column is searched and a value is returned from the last row or column in the array. If search_key is not found, a non-exact match may be returned.")),
|
|
18562
|
-
arg("result_range (range, optional)", _t("The range from which to return a result. The value returned corresponds to the location where search_key is found in search_range. This range must be only a single row or column and should not be used if using the search_result_array method.")),
|
|
18569
|
+
arg("search_array (any, range)", _t("One method of using this function is to provide a single sorted row or column search_array to look through for the search_key with a second argument result_range. The other way is to combine these two arguments into one search_array where the first row or column is searched and a value is returned from the last row or column in the array. If search_key is not found, a non-exact match may be returned.")),
|
|
18570
|
+
arg("result_range (any, range, optional)", _t("The range from which to return a result. The value returned corresponds to the location where search_key is found in search_range. This range must be only a single row or column and should not be used if using the search_result_array method.")),
|
|
18563
18571
|
],
|
|
18564
18572
|
compute: function (searchKey, searchArray, resultRange) {
|
|
18565
|
-
|
|
18566
|
-
|
|
18573
|
+
const _searchArray = toMatrix(searchArray);
|
|
18574
|
+
const _resultRange = toMatrix(resultRange);
|
|
18575
|
+
let nbCol = _searchArray.length;
|
|
18576
|
+
let nbRow = _searchArray[0].length;
|
|
18567
18577
|
const verticalSearch = nbRow >= nbCol;
|
|
18568
18578
|
const getElement = verticalSearch
|
|
18569
18579
|
? (range, index) => range[0][index].value
|
|
18570
18580
|
: (range, index) => range[index][0].value;
|
|
18571
18581
|
const rangeLength = verticalSearch ? nbRow : nbCol;
|
|
18572
|
-
const index = dichotomicSearch(
|
|
18582
|
+
const index = dichotomicSearch(_searchArray, searchKey, "nextSmaller", "asc", rangeLength, getElement);
|
|
18573
18583
|
if (index === -1 ||
|
|
18574
|
-
(verticalSearch &&
|
|
18575
|
-
(!verticalSearch &&
|
|
18584
|
+
(verticalSearch && _searchArray[0][index] === undefined) ||
|
|
18585
|
+
(!verticalSearch && _searchArray[index][nbRow - 1] === undefined)) {
|
|
18576
18586
|
return valueNotAvailable(searchKey);
|
|
18577
18587
|
}
|
|
18578
|
-
if (
|
|
18579
|
-
return verticalSearch ?
|
|
18588
|
+
if (_resultRange[0].length === 0) {
|
|
18589
|
+
return verticalSearch ? _searchArray[nbCol - 1][index] : _searchArray[index][nbRow - 1];
|
|
18580
18590
|
}
|
|
18581
|
-
nbCol =
|
|
18582
|
-
nbRow =
|
|
18591
|
+
nbCol = _resultRange.length;
|
|
18592
|
+
nbRow = _resultRange[0].length;
|
|
18583
18593
|
assert(() => nbCol === 1 || nbRow === 1, _t("The result_range must be a single row or a single column."));
|
|
18584
18594
|
if (nbCol > 1) {
|
|
18585
18595
|
assert(() => index <= nbCol - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range row value %s.", (index + 1).toString()));
|
|
18586
|
-
return
|
|
18596
|
+
return _resultRange[index][0];
|
|
18587
18597
|
}
|
|
18588
18598
|
assert(() => index <= nbRow - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range column value %s.", (index + 1).toString()));
|
|
18589
|
-
return
|
|
18599
|
+
return _resultRange[0][index];
|
|
18590
18600
|
},
|
|
18591
18601
|
isExported: true,
|
|
18592
18602
|
};
|
|
@@ -18603,28 +18613,29 @@ const MATCH = {
|
|
|
18603
18613
|
],
|
|
18604
18614
|
compute: function (searchKey, range, searchType = { value: DEFAULT_SEARCH_TYPE }) {
|
|
18605
18615
|
let _searchType = toNumber(searchType, this.locale);
|
|
18606
|
-
const
|
|
18607
|
-
const
|
|
18616
|
+
const _range = toMatrix(range);
|
|
18617
|
+
const nbCol = _range.length;
|
|
18618
|
+
const nbRow = _range[0].length;
|
|
18608
18619
|
assert(() => nbCol === 1 || nbRow === 1, _t("The range must be a single row or a single column."));
|
|
18609
18620
|
let index = -1;
|
|
18610
18621
|
const getElement = nbCol === 1
|
|
18611
|
-
? (
|
|
18612
|
-
: (
|
|
18613
|
-
const rangeLen = nbCol === 1 ?
|
|
18622
|
+
? (_range, index) => _range[0][index].value
|
|
18623
|
+
: (_range, index) => _range[index][0].value;
|
|
18624
|
+
const rangeLen = nbCol === 1 ? _range[0].length : _range.length;
|
|
18614
18625
|
_searchType = Math.sign(_searchType);
|
|
18615
18626
|
switch (_searchType) {
|
|
18616
18627
|
case 1:
|
|
18617
|
-
index = dichotomicSearch(
|
|
18628
|
+
index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
|
|
18618
18629
|
break;
|
|
18619
18630
|
case 0:
|
|
18620
|
-
index = linearSearch(
|
|
18631
|
+
index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement);
|
|
18621
18632
|
break;
|
|
18622
18633
|
case -1:
|
|
18623
|
-
index = dichotomicSearch(
|
|
18634
|
+
index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
|
|
18624
18635
|
break;
|
|
18625
18636
|
}
|
|
18626
|
-
if ((nbCol === 1 &&
|
|
18627
|
-
(nbCol !== 1 &&
|
|
18637
|
+
if ((nbCol === 1 && _range[0][index] === undefined) ||
|
|
18638
|
+
(nbCol !== 1 && _range[index] === undefined)) {
|
|
18628
18639
|
return valueNotAvailable(searchKey);
|
|
18629
18640
|
}
|
|
18630
18641
|
return index + 1;
|
|
@@ -18679,13 +18690,14 @@ const VLOOKUP = {
|
|
|
18679
18690
|
],
|
|
18680
18691
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18681
18692
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18682
|
-
|
|
18693
|
+
const _range = toMatrix(range);
|
|
18694
|
+
assert(() => 1 <= _index && _index <= _range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18683
18695
|
const getValueFromRange = (range, index) => range[0][index].value;
|
|
18684
18696
|
const _isSorted = toBoolean(isSorted.value);
|
|
18685
18697
|
const rowIndex = _isSorted
|
|
18686
|
-
? dichotomicSearch(
|
|
18687
|
-
: linearSearch(
|
|
18688
|
-
const value =
|
|
18698
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range[0].length, getValueFromRange)
|
|
18699
|
+
: linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange);
|
|
18700
|
+
const value = _range[_index - 1][rowIndex];
|
|
18689
18701
|
if (value === undefined) {
|
|
18690
18702
|
return valueNotAvailable(searchKey);
|
|
18691
18703
|
}
|
|
@@ -18722,27 +18734,29 @@ const XLOOKUP = {
|
|
|
18722
18734
|
compute: function (searchKey, lookupRange, returnRange, defaultValue, matchMode = { value: DEFAULT_MATCH_MODE }, searchMode = { value: DEFAULT_SEARCH_MODE }) {
|
|
18723
18735
|
const _matchMode = Math.trunc(toNumber(matchMode.value, this.locale));
|
|
18724
18736
|
const _searchMode = Math.trunc(toNumber(searchMode.value, this.locale));
|
|
18725
|
-
|
|
18737
|
+
const _lookupRange = toMatrix(lookupRange);
|
|
18738
|
+
const _returnRange = toMatrix(returnRange);
|
|
18739
|
+
assert(() => _lookupRange.length === 1 || _lookupRange[0].length === 1, _t("lookup_range should be either a single row or single column."));
|
|
18726
18740
|
assert(() => [-1, 1, -2, 2].includes(_searchMode), _t("search_mode should be a value in [-1, 1, -2, 2]."));
|
|
18727
18741
|
assert(() => [-1, 0, 1, 2].includes(_matchMode), _t("match_mode should be a value in [-1, 0, 1, 2]."));
|
|
18728
|
-
const lookupDirection =
|
|
18742
|
+
const lookupDirection = _lookupRange.length === 1 ? "col" : "row";
|
|
18729
18743
|
assert(() => !(_matchMode === 2 && [-2, 2].includes(_searchMode)), _t("the search and match mode combination is not supported for XLOOKUP evaluation."));
|
|
18730
18744
|
assert(() => lookupDirection === "col"
|
|
18731
|
-
?
|
|
18732
|
-
:
|
|
18745
|
+
? _returnRange[0].length === _lookupRange[0].length
|
|
18746
|
+
: _returnRange.length === _lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
|
|
18733
18747
|
const getElement = lookupDirection === "col"
|
|
18734
18748
|
? (range, index) => range[0][index].value
|
|
18735
18749
|
: (range, index) => range[index][0].value;
|
|
18736
|
-
const rangeLen = lookupDirection === "col" ?
|
|
18750
|
+
const rangeLen = lookupDirection === "col" ? _lookupRange[0].length : _lookupRange.length;
|
|
18737
18751
|
const mode = MATCH_MODE[_matchMode];
|
|
18738
18752
|
const reverseSearch = _searchMode === -1;
|
|
18739
18753
|
const index = _searchMode === 2 || _searchMode === -2
|
|
18740
|
-
? dichotomicSearch(
|
|
18741
|
-
: linearSearch(
|
|
18754
|
+
? dichotomicSearch(_lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
|
|
18755
|
+
: linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, reverseSearch);
|
|
18742
18756
|
if (index !== -1) {
|
|
18743
18757
|
return lookupDirection === "col"
|
|
18744
|
-
?
|
|
18745
|
-
: [
|
|
18758
|
+
? _returnRange.map((col) => [col[index]])
|
|
18759
|
+
: [_returnRange[index]];
|
|
18746
18760
|
}
|
|
18747
18761
|
if (defaultValue === undefined) {
|
|
18748
18762
|
return valueNotAvailable(searchKey);
|
|
@@ -28434,11 +28448,7 @@ function interpolateData(config, values, labels, newLabels) {
|
|
|
28434
28448
|
if (values.length < 2 || labels.length < 2 || newLabels.length === 0) {
|
|
28435
28449
|
return [];
|
|
28436
28450
|
}
|
|
28437
|
-
const
|
|
28438
|
-
const labelMax = Math.max(...labels);
|
|
28439
|
-
const labelRange = labelMax - labelMin;
|
|
28440
|
-
const normalizedLabels = labels.map((v) => (v - labelMin) / labelRange);
|
|
28441
|
-
const normalizedNewLabels = newLabels.map((v) => (v - labelMin) / labelRange);
|
|
28451
|
+
const { normalizedLabels, normalizedNewLabels } = normalizeLabels(labels, newLabels, config);
|
|
28442
28452
|
try {
|
|
28443
28453
|
switch (config.type) {
|
|
28444
28454
|
case "polynomial": {
|
|
@@ -28483,6 +28493,30 @@ function interpolateData(config, values, labels, newLabels) {
|
|
|
28483
28493
|
return newLabels.map((x) => ({ x, y: NaN }));
|
|
28484
28494
|
}
|
|
28485
28495
|
}
|
|
28496
|
+
function normalizeLabels(labels, newLabels, config) {
|
|
28497
|
+
let normalizedLabels = [];
|
|
28498
|
+
let normalizedNewLabels = [];
|
|
28499
|
+
if (config.type === "logarithmic") {
|
|
28500
|
+
// Logarithmic trends in charts are used to visualize proportional growth or
|
|
28501
|
+
// relative changes. Therefore, we change the normalization technique for
|
|
28502
|
+
// logarithmic trend lines for a better fit. The method used here is Max Absolute
|
|
28503
|
+
// Scaling. This Technique is ideal for data spanning several orders of magnitude,
|
|
28504
|
+
// as it balances differences between small and large values by compressing larger
|
|
28505
|
+
// values while preserving proportionality and ensuring all values are scaled relative
|
|
28506
|
+
// to the largest magnitude.
|
|
28507
|
+
const labelMax = Math.max(...labels.map(Math.abs));
|
|
28508
|
+
normalizedLabels = labels.map((l) => l / labelMax);
|
|
28509
|
+
normalizedNewLabels = newLabels.map((l) => l / labelMax);
|
|
28510
|
+
}
|
|
28511
|
+
else {
|
|
28512
|
+
const labelMax = Math.max(...labels);
|
|
28513
|
+
const labelMin = Math.min(...labels);
|
|
28514
|
+
const labelRange = labelMax - labelMin;
|
|
28515
|
+
normalizedLabels = labels.map((l) => (l - labelMax) / labelRange);
|
|
28516
|
+
normalizedNewLabels = newLabels.map((l) => (l - labelMax) / labelRange);
|
|
28517
|
+
}
|
|
28518
|
+
return { normalizedLabels, normalizedNewLabels };
|
|
28519
|
+
}
|
|
28486
28520
|
function getChartAxisType(chart, labelRange, getters) {
|
|
28487
28521
|
if (isDateChart(chart, labelRange, getters) && isLuxonTimeAdapterInstalled()) {
|
|
28488
28522
|
return "time";
|
|
@@ -41002,8 +41036,8 @@ function useDragAndDropListItems() {
|
|
|
41002
41036
|
document.body.style.cursor = "move";
|
|
41003
41037
|
state.draggedItemId = args.draggedItemId;
|
|
41004
41038
|
const container = direction === "horizontal"
|
|
41005
|
-
? new HorizontalContainer(args.
|
|
41006
|
-
: new VerticalContainer(args.
|
|
41039
|
+
? new HorizontalContainer(args.scrollableContainerEl)
|
|
41040
|
+
: new VerticalContainer(args.scrollableContainerEl);
|
|
41007
41041
|
dndHelper = new DOMDndHelper({
|
|
41008
41042
|
...args,
|
|
41009
41043
|
container,
|
|
@@ -41014,8 +41048,8 @@ function useDragAndDropListItems() {
|
|
|
41014
41048
|
const stopListening = startDnd(dndHelper.onMouseMove.bind(dndHelper), dndHelper.onMouseUp.bind(dndHelper));
|
|
41015
41049
|
cleanupFns.push(stopListening);
|
|
41016
41050
|
const onScroll = dndHelper.onScroll.bind(dndHelper);
|
|
41017
|
-
args.
|
|
41018
|
-
cleanupFns.push(() => args.
|
|
41051
|
+
args.scrollableContainerEl.addEventListener("scroll", onScroll);
|
|
41052
|
+
cleanupFns.push(() => args.scrollableContainerEl.removeEventListener("scroll", onScroll));
|
|
41019
41053
|
cleanupFns.push(dndHelper.destroy.bind(dndHelper));
|
|
41020
41054
|
};
|
|
41021
41055
|
onWillUnmount(() => {
|
|
@@ -41472,7 +41506,7 @@ class ConditionalFormatPreviewList extends Component {
|
|
|
41472
41506
|
draggedItemId: cf.id,
|
|
41473
41507
|
initialMousePosition: event.clientY,
|
|
41474
41508
|
items: items,
|
|
41475
|
-
|
|
41509
|
+
scrollableContainerEl: this.cfListRef.el,
|
|
41476
41510
|
onDragEnd: (cfId, finalIndex) => this.onDragEnd(cfId, finalIndex),
|
|
41477
41511
|
});
|
|
41478
41512
|
}
|
|
@@ -44654,6 +44688,7 @@ class PivotLayoutConfigurator extends Component {
|
|
|
44654
44688
|
unusedGranularities: Object,
|
|
44655
44689
|
dateGranularities: Array,
|
|
44656
44690
|
datetimeGranularities: Array,
|
|
44691
|
+
getScrollableContainerEl: { type: Function, optional: true },
|
|
44657
44692
|
pivotId: String,
|
|
44658
44693
|
};
|
|
44659
44694
|
dimensionsRef = useRef("pivot-dimensions");
|
|
@@ -44687,7 +44722,7 @@ class PivotLayoutConfigurator extends Component {
|
|
|
44687
44722
|
draggedItemId: dimension.nameWithGranularity,
|
|
44688
44723
|
initialMousePosition: event.clientY,
|
|
44689
44724
|
items: draggableItems,
|
|
44690
|
-
|
|
44725
|
+
scrollableContainerEl: this.props.getScrollableContainerEl?.() || this.dimensionsRef.el,
|
|
44691
44726
|
onDragEnd: (dimensionName, finalIndex) => {
|
|
44692
44727
|
const originalIndex = draggableIds.findIndex((id) => id === dimensionName);
|
|
44693
44728
|
if (originalIndex === finalIndex) {
|
|
@@ -44736,7 +44771,7 @@ class PivotLayoutConfigurator extends Component {
|
|
|
44736
44771
|
draggedItemId: measure.id,
|
|
44737
44772
|
initialMousePosition: event.clientY,
|
|
44738
44773
|
items: draggableItems,
|
|
44739
|
-
|
|
44774
|
+
scrollableContainerEl: this.props.getScrollableContainerEl?.() || this.dimensionsRef.el,
|
|
44740
44775
|
onDragEnd: (measureName, finalIndex) => {
|
|
44741
44776
|
const originalIndex = draggableIds.findIndex((id) => id === measureName);
|
|
44742
44777
|
if (originalIndex === finalIndex) {
|
|
@@ -45369,7 +45404,7 @@ class SpreadsheetPivotTable {
|
|
|
45369
45404
|
rowTreeToRows(tree, parentRow) {
|
|
45370
45405
|
return tree.flatMap((node) => {
|
|
45371
45406
|
const row = {
|
|
45372
|
-
indent: parentRow ? parentRow.indent + 1 :
|
|
45407
|
+
indent: parentRow ? parentRow.indent + 1 : 1,
|
|
45373
45408
|
fields: [...(parentRow?.fields || []), node.field],
|
|
45374
45409
|
values: [...(parentRow?.values || []), node.value],
|
|
45375
45410
|
};
|
|
@@ -45425,7 +45460,7 @@ function dataEntriesToRows(dataEntries, index, rows, fields, values) {
|
|
|
45425
45460
|
pivotTableRows.push({
|
|
45426
45461
|
fields: _fields,
|
|
45427
45462
|
values: _values,
|
|
45428
|
-
indent: index,
|
|
45463
|
+
indent: index + 1,
|
|
45429
45464
|
});
|
|
45430
45465
|
const record = groups[value];
|
|
45431
45466
|
if (record) {
|
|
@@ -46423,6 +46458,7 @@ class PivotSpreadsheetSidePanel extends Component {
|
|
|
46423
46458
|
};
|
|
46424
46459
|
store;
|
|
46425
46460
|
state;
|
|
46461
|
+
pivotSidePanelRef = useRef("pivotSidePanel");
|
|
46426
46462
|
setup() {
|
|
46427
46463
|
this.store = useLocalStore(PivotSidePanelStore, this.props.pivotId);
|
|
46428
46464
|
this.state = useState({
|
|
@@ -46451,6 +46487,9 @@ class PivotSpreadsheetSidePanel extends Component {
|
|
|
46451
46487
|
get definition() {
|
|
46452
46488
|
return this.store.definition;
|
|
46453
46489
|
}
|
|
46490
|
+
getScrollableContainerEl() {
|
|
46491
|
+
return this.pivotSidePanelRef.el;
|
|
46492
|
+
}
|
|
46454
46493
|
onSelectionChanged(ranges) {
|
|
46455
46494
|
this.state.rangeHasChanged = true;
|
|
46456
46495
|
this.state.range = ranges[0];
|
|
@@ -50486,11 +50525,10 @@ class GridRenderer {
|
|
|
50486
50525
|
switch (layer) {
|
|
50487
50526
|
case "Background":
|
|
50488
50527
|
this.drawGlobalBackground(renderingContext);
|
|
50489
|
-
for (const zone of this.getters.
|
|
50528
|
+
for (const { zone, rect } of this.getters.getAllActiveViewportsZonesAndRect()) {
|
|
50490
50529
|
const { ctx } = renderingContext;
|
|
50491
50530
|
ctx.save();
|
|
50492
50531
|
ctx.beginPath();
|
|
50493
|
-
const rect = this.getters.getVisibleRect(zone);
|
|
50494
50532
|
ctx.rect(rect.x, rect.y, rect.width, rect.height);
|
|
50495
50533
|
ctx.clip();
|
|
50496
50534
|
const boxes = this.getGridBoxes(zone);
|
|
@@ -50766,10 +50804,8 @@ class GridRenderer {
|
|
|
50766
50804
|
const { ctx, thinLineWidth } = renderingContext;
|
|
50767
50805
|
const visibleCols = this.getters.getSheetViewVisibleCols();
|
|
50768
50806
|
const left = visibleCols[0];
|
|
50769
|
-
const right = visibleCols[visibleCols.length - 1];
|
|
50770
50807
|
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
50771
50808
|
const top = visibleRows[0];
|
|
50772
|
-
const bottom = visibleRows[visibleRows.length - 1];
|
|
50773
50809
|
const { width, height } = this.getters.getSheetViewDimensionWithHeaders();
|
|
50774
50810
|
const selection = this.getters.getSelectedZones();
|
|
50775
50811
|
const selectedCols = getZonesCols(selection);
|
|
@@ -50785,7 +50821,7 @@ class GridRenderer {
|
|
|
50785
50821
|
ctx.lineWidth = thinLineWidth;
|
|
50786
50822
|
ctx.strokeStyle = "#333";
|
|
50787
50823
|
// Columns headers background
|
|
50788
|
-
for (
|
|
50824
|
+
for (const col of visibleCols) {
|
|
50789
50825
|
const colZone = { left: col, right: col, top: 0, bottom: numberOfRows - 1 };
|
|
50790
50826
|
const { x, width } = this.getters.getVisibleRect(colZone);
|
|
50791
50827
|
const isColActive = activeCols.has(col);
|
|
@@ -50802,7 +50838,7 @@ class GridRenderer {
|
|
|
50802
50838
|
ctx.fillRect(x, 0, width, HEADER_HEIGHT);
|
|
50803
50839
|
}
|
|
50804
50840
|
// Rows headers background
|
|
50805
|
-
for (
|
|
50841
|
+
for (const row of visibleRows) {
|
|
50806
50842
|
const rowZone = { top: row, bottom: row, left: 0, right: numberOfCols - 1 };
|
|
50807
50843
|
const { y, height } = this.getters.getVisibleRect(rowZone);
|
|
50808
50844
|
const isRowActive = activeRows.has(row);
|
|
@@ -50828,21 +50864,21 @@ class GridRenderer {
|
|
|
50828
50864
|
ctx.stroke();
|
|
50829
50865
|
ctx.beginPath();
|
|
50830
50866
|
// column text + separator
|
|
50831
|
-
for (const
|
|
50832
|
-
const colSize = this.getters.getColSize(sheetId,
|
|
50833
|
-
const colName = numberToLetters(
|
|
50834
|
-
ctx.fillStyle = activeCols.has(
|
|
50835
|
-
let colStart = this.getHeaderOffset("COL", left,
|
|
50867
|
+
for (const col of visibleCols) {
|
|
50868
|
+
const colSize = this.getters.getColSize(sheetId, col);
|
|
50869
|
+
const colName = numberToLetters(col);
|
|
50870
|
+
ctx.fillStyle = activeCols.has(col) ? "#fff" : TEXT_HEADER_COLOR;
|
|
50871
|
+
let colStart = this.getHeaderOffset("COL", left, col);
|
|
50836
50872
|
ctx.fillText(colName, colStart + colSize / 2, HEADER_HEIGHT / 2);
|
|
50837
50873
|
ctx.moveTo(colStart + colSize, 0);
|
|
50838
50874
|
ctx.lineTo(colStart + colSize, HEADER_HEIGHT);
|
|
50839
50875
|
}
|
|
50840
50876
|
// row text + separator
|
|
50841
|
-
for (const
|
|
50842
|
-
const rowSize = this.getters.getRowSize(sheetId,
|
|
50843
|
-
ctx.fillStyle = activeRows.has(
|
|
50844
|
-
let rowStart = this.getHeaderOffset("ROW", top,
|
|
50845
|
-
ctx.fillText(String(
|
|
50877
|
+
for (const row of visibleRows) {
|
|
50878
|
+
const rowSize = this.getters.getRowSize(sheetId, row);
|
|
50879
|
+
ctx.fillStyle = activeRows.has(row) ? "#fff" : TEXT_HEADER_COLOR;
|
|
50880
|
+
let rowStart = this.getHeaderOffset("ROW", top, row);
|
|
50881
|
+
ctx.fillText(String(row + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
|
|
50846
50882
|
ctx.moveTo(0, rowStart + rowSize);
|
|
50847
50883
|
ctx.lineTo(HEADER_WIDTH, rowStart + rowSize);
|
|
50848
50884
|
}
|
|
@@ -51149,6 +51185,9 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
51149
51185
|
canvas.width = width * dpr;
|
|
51150
51186
|
canvas.height = height * dpr;
|
|
51151
51187
|
canvas.setAttribute("style", `width:${width}px;height:${height}px;`);
|
|
51188
|
+
if (width === 0 || height === 0) {
|
|
51189
|
+
return;
|
|
51190
|
+
}
|
|
51152
51191
|
// Imagine each pixel as a large square. The whole-number coordinates (0, 1, 2…)
|
|
51153
51192
|
// are the edges of the squares. If you draw a one-unit-wide line between whole-number
|
|
51154
51193
|
// coordinates, it will overlap opposite sides of the pixel square, and the resulting
|
|
@@ -52695,7 +52734,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
52695
52734
|
getCommonSides(border1, border2) {
|
|
52696
52735
|
const commonBorder = {};
|
|
52697
52736
|
for (let side of ["top", "bottom", "left", "right"]) {
|
|
52698
|
-
if (border1[side] && border1[side]
|
|
52737
|
+
if (border1[side] && deepEquals(border1[side], border2[side])) {
|
|
52699
52738
|
commonBorder[side] = border1[side];
|
|
52700
52739
|
}
|
|
52701
52740
|
}
|
|
@@ -66911,8 +66950,17 @@ class InternalViewport {
|
|
|
66911
66950
|
this.getters = getters;
|
|
66912
66951
|
this.sheetId = sheetId;
|
|
66913
66952
|
this.boundaries = boundaries;
|
|
66914
|
-
|
|
66915
|
-
|
|
66953
|
+
if (sizeInGrid.width < 0 || sizeInGrid.height < 0) {
|
|
66954
|
+
throw new Error("Viewport size cannot be negative");
|
|
66955
|
+
}
|
|
66956
|
+
this.viewportWidth = sizeInGrid.height && sizeInGrid.width;
|
|
66957
|
+
this.viewportHeight = sizeInGrid.width && sizeInGrid.height;
|
|
66958
|
+
this.top = boundaries.top;
|
|
66959
|
+
this.bottom = boundaries.bottom;
|
|
66960
|
+
this.left = boundaries.left;
|
|
66961
|
+
this.right = boundaries.right;
|
|
66962
|
+
this.offsetX = offsets.x;
|
|
66963
|
+
this.offsetY = offsets.y;
|
|
66916
66964
|
this.offsetScrollbarX = offsets.x;
|
|
66917
66965
|
this.offsetScrollbarY = offsets.y;
|
|
66918
66966
|
this.canScrollVertically = options.canScrollVertically;
|
|
@@ -66955,9 +67003,9 @@ class InternalViewport {
|
|
|
66955
67003
|
Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
|
|
66956
67004
|
);
|
|
66957
67005
|
height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
|
|
66958
|
-
|
|
66959
|
-
|
|
66960
|
-
|
|
67006
|
+
if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
|
|
67007
|
+
height += FOOTER_HEIGHT;
|
|
67008
|
+
}
|
|
66961
67009
|
}
|
|
66962
67010
|
return { width, height };
|
|
66963
67011
|
}
|
|
@@ -67098,6 +67146,9 @@ class InternalViewport {
|
|
|
67098
67146
|
!this.getters.isRowHidden(this.sheetId, row));
|
|
67099
67147
|
}
|
|
67100
67148
|
searchHeaderIndex(dimension, position, startIndex = 0) {
|
|
67149
|
+
if (this.viewportWidth <= 0 || this.viewportHeight <= 0) {
|
|
67150
|
+
return -1;
|
|
67151
|
+
}
|
|
67101
67152
|
const sheetId = this.sheetId;
|
|
67102
67153
|
const headers = this.getters.getNumberHeaders(sheetId, dimension);
|
|
67103
67154
|
// using a binary search:
|
|
@@ -67134,7 +67185,7 @@ class InternalViewport {
|
|
|
67134
67185
|
this.adjustViewportZoneY();
|
|
67135
67186
|
}
|
|
67136
67187
|
/** Corrects the viewport's horizontal offset based on the current structure
|
|
67137
|
-
* To make sure that at least
|
|
67188
|
+
* To make sure that at least one column is visible inside the viewport.
|
|
67138
67189
|
*/
|
|
67139
67190
|
adjustViewportOffsetX() {
|
|
67140
67191
|
if (this.canScrollHorizontally) {
|
|
@@ -67146,7 +67197,7 @@ class InternalViewport {
|
|
|
67146
67197
|
this.adjustViewportZoneX();
|
|
67147
67198
|
}
|
|
67148
67199
|
/** Corrects the viewport's vertical offset based on the current structure
|
|
67149
|
-
* To make sure that at least
|
|
67200
|
+
* To make sure that at least one row is visible inside the viewport.
|
|
67150
67201
|
*/
|
|
67151
67202
|
adjustViewportOffsetY() {
|
|
67152
67203
|
if (this.canScrollVertically) {
|
|
@@ -67163,11 +67214,14 @@ class InternalViewport {
|
|
|
67163
67214
|
const sheetId = this.sheetId;
|
|
67164
67215
|
this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
|
|
67165
67216
|
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
|
|
67217
|
+
if (!this.viewportWidth) {
|
|
67218
|
+
return;
|
|
67219
|
+
}
|
|
67166
67220
|
if (this.left === -1) {
|
|
67167
67221
|
this.left = this.boundaries.left;
|
|
67168
67222
|
}
|
|
67169
67223
|
if (this.right === -1) {
|
|
67170
|
-
this.right = this.
|
|
67224
|
+
this.right = this.boundaries.right;
|
|
67171
67225
|
}
|
|
67172
67226
|
this.offsetX =
|
|
67173
67227
|
this.getters.getColDimensions(sheetId, this.left).start -
|
|
@@ -67179,11 +67233,14 @@ class InternalViewport {
|
|
|
67179
67233
|
const sheetId = this.sheetId;
|
|
67180
67234
|
this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
|
|
67181
67235
|
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
|
|
67236
|
+
if (!this.viewportHeight) {
|
|
67237
|
+
return;
|
|
67238
|
+
}
|
|
67182
67239
|
if (this.top === -1) {
|
|
67183
67240
|
this.top = this.boundaries.top;
|
|
67184
67241
|
}
|
|
67185
67242
|
if (this.bottom === -1) {
|
|
67186
|
-
this.bottom = this.
|
|
67243
|
+
this.bottom = this.boundaries.bottom;
|
|
67187
67244
|
}
|
|
67188
67245
|
this.offsetY =
|
|
67189
67246
|
this.getters.getRowDimensions(sheetId, this.top).start -
|
|
@@ -67257,7 +67314,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67257
67314
|
"isPositionVisible",
|
|
67258
67315
|
"getColDimensionsInViewport",
|
|
67259
67316
|
"getRowDimensionsInViewport",
|
|
67260
|
-
"
|
|
67317
|
+
"getAllActiveViewportsZonesAndRect",
|
|
67261
67318
|
"getRect",
|
|
67262
67319
|
];
|
|
67263
67320
|
viewports = {};
|
|
@@ -67487,12 +67544,12 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67487
67544
|
const sheetId = this.getters.getActiveSheetId();
|
|
67488
67545
|
const viewports = this.getSubViewports(sheetId);
|
|
67489
67546
|
//TODO ake another commit to eimprove this
|
|
67490
|
-
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
67547
|
+
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => col >= 0 && !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
67491
67548
|
}
|
|
67492
67549
|
getSheetViewVisibleRows() {
|
|
67493
67550
|
const sheetId = this.getters.getActiveSheetId();
|
|
67494
67551
|
const viewports = this.getSubViewports(sheetId);
|
|
67495
|
-
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
67552
|
+
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => row >= 0 && !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
67496
67553
|
}
|
|
67497
67554
|
/**
|
|
67498
67555
|
* Get the positions of all the cells that are visible in the viewport, taking merges into account.
|
|
@@ -67535,19 +67592,19 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67535
67592
|
maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
|
|
67536
67593
|
};
|
|
67537
67594
|
}
|
|
67538
|
-
getColRowOffsetInViewport(dimension,
|
|
67539
|
-
|
|
67540
|
-
|
|
67541
|
-
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
67542
|
-
if (index < referenceIndex) {
|
|
67543
|
-
return -this.getColRowOffsetInViewport(dimension, index, referenceIndex);
|
|
67595
|
+
getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
|
|
67596
|
+
if (targetHeaderIndex < referenceHeaderIndex) {
|
|
67597
|
+
return -this.getColRowOffsetInViewport(dimension, targetHeaderIndex, referenceHeaderIndex);
|
|
67544
67598
|
}
|
|
67599
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
67600
|
+
const visibleHeaders = dimension === "COL"
|
|
67601
|
+
? this.getters.getSheetViewVisibleCols()
|
|
67602
|
+
: this.getters.getSheetViewVisibleRows();
|
|
67603
|
+
const startIndex = visibleHeaders.findIndex((header) => referenceHeaderIndex >= header);
|
|
67604
|
+
const endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
|
|
67605
|
+
const relevantIndexes = visibleHeaders.slice(startIndex, endIndex);
|
|
67545
67606
|
let offset = 0;
|
|
67546
|
-
const
|
|
67547
|
-
for (let i = referenceIndex; i < index; i++) {
|
|
67548
|
-
if (!visibleIndexes.includes(i)) {
|
|
67549
|
-
continue;
|
|
67550
|
-
}
|
|
67607
|
+
for (const i of relevantIndexes) {
|
|
67551
67608
|
offset += this.getters.getHeaderSize(sheetId, dimension, i);
|
|
67552
67609
|
}
|
|
67553
67610
|
return offset;
|
|
@@ -67594,7 +67651,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67594
67651
|
}
|
|
67595
67652
|
return { canEdgeScroll, direction, delay };
|
|
67596
67653
|
}
|
|
67597
|
-
getEdgeScrollRow(y, previousY,
|
|
67654
|
+
getEdgeScrollRow(y, previousY, startingY) {
|
|
67598
67655
|
let canEdgeScroll = false;
|
|
67599
67656
|
let direction = 0;
|
|
67600
67657
|
let delay = 0;
|
|
@@ -67615,7 +67672,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67615
67672
|
delay = scrollDelay(y - height);
|
|
67616
67673
|
direction = 1;
|
|
67617
67674
|
}
|
|
67618
|
-
else if (y < offsetCorrectionY &&
|
|
67675
|
+
else if (y < offsetCorrectionY && startingY >= offsetCorrectionY && currentOffsetY > 0) {
|
|
67619
67676
|
// 2
|
|
67620
67677
|
canEdgeScroll = true;
|
|
67621
67678
|
delay = scrollDelay(offsetCorrectionY - y);
|
|
@@ -67641,13 +67698,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67641
67698
|
*/
|
|
67642
67699
|
getVisibleRectWithoutHeaders(zone) {
|
|
67643
67700
|
const sheetId = this.getters.getActiveSheetId();
|
|
67644
|
-
|
|
67645
|
-
.map((viewport) => viewport.getVisibleRect(zone))
|
|
67646
|
-
.filter(isDefined);
|
|
67647
|
-
if (viewportRects.length === 0) {
|
|
67648
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
67649
|
-
}
|
|
67650
|
-
return this.recomposeRect(viewportRects);
|
|
67701
|
+
return this.mapViewportsToRect(sheetId, (viewport) => viewport.getVisibleRect(zone));
|
|
67651
67702
|
}
|
|
67652
67703
|
/**
|
|
67653
67704
|
* Computes the actual size and position (:Rect) of the zone on the canvas
|
|
@@ -67655,13 +67706,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67655
67706
|
*/
|
|
67656
67707
|
getRect(zone) {
|
|
67657
67708
|
const sheetId = this.getters.getActiveSheetId();
|
|
67658
|
-
const
|
|
67659
|
-
.map((viewport) => viewport.getFullRect(zone))
|
|
67660
|
-
.filter(isDefined);
|
|
67661
|
-
if (viewportRects.length === 0) {
|
|
67662
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
67663
|
-
}
|
|
67664
|
-
const rect = this.recomposeRect(viewportRects);
|
|
67709
|
+
const rect = this.mapViewportsToRect(sheetId, (viewport) => viewport.getFullRect(zone));
|
|
67665
67710
|
return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
|
|
67666
67711
|
}
|
|
67667
67712
|
/**
|
|
@@ -67706,9 +67751,18 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67706
67751
|
end: start + (isRowHidden ? 0 : size),
|
|
67707
67752
|
};
|
|
67708
67753
|
}
|
|
67709
|
-
|
|
67754
|
+
getAllActiveViewportsZonesAndRect() {
|
|
67710
67755
|
const sheetId = this.getters.getActiveSheetId();
|
|
67711
|
-
return this.getSubViewports(sheetId)
|
|
67756
|
+
return this.getSubViewports(sheetId).map((viewport) => {
|
|
67757
|
+
return {
|
|
67758
|
+
zone: viewport,
|
|
67759
|
+
rect: {
|
|
67760
|
+
x: viewport.offsetCorrectionX + this.gridOffsetX,
|
|
67761
|
+
y: viewport.offsetCorrectionY + this.gridOffsetY,
|
|
67762
|
+
...viewport.getMaxSize(),
|
|
67763
|
+
},
|
|
67764
|
+
};
|
|
67765
|
+
});
|
|
67712
67766
|
}
|
|
67713
67767
|
// ---------------------------------------------------------------------------
|
|
67714
67768
|
// Private
|
|
@@ -67767,12 +67821,11 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67767
67821
|
}
|
|
67768
67822
|
/** gets rid of deprecated sheetIds */
|
|
67769
67823
|
cleanViewports() {
|
|
67770
|
-
const
|
|
67771
|
-
for (
|
|
67772
|
-
|
|
67773
|
-
delete this.viewports[sheetId];
|
|
67774
|
-
}
|
|
67824
|
+
const newViewport = {};
|
|
67825
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
67826
|
+
newViewport[sheetId] = this.viewports[sheetId];
|
|
67775
67827
|
}
|
|
67828
|
+
this.viewports = newViewport;
|
|
67776
67829
|
}
|
|
67777
67830
|
resizeSheetView(height, width, gridOffsetX = 0, gridOffsetY = 0) {
|
|
67778
67831
|
this.sheetViewHeight = height;
|
|
@@ -67782,7 +67835,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67782
67835
|
this.recomputeViewports();
|
|
67783
67836
|
}
|
|
67784
67837
|
recomputeViewports() {
|
|
67785
|
-
for (
|
|
67838
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
67786
67839
|
this.resetViewports(sheetId);
|
|
67787
67840
|
}
|
|
67788
67841
|
}
|
|
@@ -67804,8 +67857,10 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67804
67857
|
const { xSplit, ySplit } = this.getters.getPaneDivisions(sheetId);
|
|
67805
67858
|
const nCols = this.getters.getNumberCols(sheetId);
|
|
67806
67859
|
const nRows = this.getters.getNumberRows(sheetId);
|
|
67807
|
-
const colOffset = this.getters.getColRowOffset("COL", 0, xSplit, sheetId);
|
|
67808
|
-
const rowOffset = this.getters.getColRowOffset("ROW", 0, ySplit, sheetId);
|
|
67860
|
+
const colOffset = Math.min(this.getters.getColRowOffset("COL", 0, xSplit, sheetId), this.sheetViewWidth);
|
|
67861
|
+
const rowOffset = Math.min(this.getters.getColRowOffset("ROW", 0, ySplit, sheetId), this.sheetViewHeight);
|
|
67862
|
+
const unfrozenWidth = Math.max(this.sheetViewWidth - colOffset, 0);
|
|
67863
|
+
const unfrozenHeight = Math.max(this.sheetViewHeight - rowOffset, 0);
|
|
67809
67864
|
const { xRatio, yRatio } = this.getFrozenSheetViewRatio(sheetId);
|
|
67810
67865
|
const canScrollHorizontally = xRatio < 1.0;
|
|
67811
67866
|
const canScrollVertically = yRatio < 1.0;
|
|
@@ -67816,14 +67871,14 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67816
67871
|
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: 0, bottom: ySplit - 1 }, { width: colOffset, height: rowOffset }, { canScrollHorizontally: false, canScrollVertically: false }, { x: 0, y: 0 })) ||
|
|
67817
67872
|
undefined,
|
|
67818
67873
|
topRight: (ySplit &&
|
|
67819
|
-
new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: 0, bottom: ySplit - 1 }, { width:
|
|
67874
|
+
new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: 0, bottom: ySplit - 1 }, { width: unfrozenWidth, height: rowOffset }, { canScrollHorizontally, canScrollVertically: false }, { x: canScrollHorizontally ? previousOffset.x : 0, y: 0 })) ||
|
|
67820
67875
|
undefined,
|
|
67821
67876
|
bottomLeft: (xSplit &&
|
|
67822
|
-
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: ySplit, bottom: nRows - 1 }, { width: colOffset, height:
|
|
67877
|
+
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: ySplit, bottom: nRows - 1 }, { width: colOffset, height: unfrozenHeight }, { canScrollHorizontally: false, canScrollVertically }, { x: 0, y: canScrollVertically ? previousOffset.y : 0 })) ||
|
|
67823
67878
|
undefined,
|
|
67824
67879
|
bottomRight: new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: ySplit, bottom: nRows - 1 }, {
|
|
67825
|
-
width:
|
|
67826
|
-
height:
|
|
67880
|
+
width: unfrozenWidth,
|
|
67881
|
+
height: unfrozenHeight,
|
|
67827
67882
|
}, { canScrollHorizontally, canScrollVertically }, {
|
|
67828
67883
|
x: canScrollHorizontally ? previousOffset.x : 0,
|
|
67829
67884
|
y: canScrollVertically ? previousOffset.y : 0,
|
|
@@ -67900,12 +67955,26 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67900
67955
|
const height = this.sheetViewHeight + this.gridOffsetY;
|
|
67901
67956
|
return { xRatio: offsetCorrectionX / width, yRatio: offsetCorrectionY / height };
|
|
67902
67957
|
}
|
|
67903
|
-
|
|
67904
|
-
|
|
67905
|
-
|
|
67906
|
-
|
|
67907
|
-
|
|
67908
|
-
|
|
67958
|
+
mapViewportsToRect(sheetId, rectCallBack) {
|
|
67959
|
+
let x = Infinity;
|
|
67960
|
+
let y = Infinity;
|
|
67961
|
+
let width = 0;
|
|
67962
|
+
let height = 0;
|
|
67963
|
+
let hasViewports = false;
|
|
67964
|
+
for (const viewport of this.getSubViewports(sheetId)) {
|
|
67965
|
+
const rect = rectCallBack(viewport);
|
|
67966
|
+
if (rect) {
|
|
67967
|
+
hasViewports = true;
|
|
67968
|
+
x = Math.min(x, rect.x);
|
|
67969
|
+
y = Math.min(y, rect.y);
|
|
67970
|
+
width = Math.max(width, rect.x + rect.width);
|
|
67971
|
+
height = Math.max(height, rect.y + rect.height);
|
|
67972
|
+
}
|
|
67973
|
+
}
|
|
67974
|
+
if (!hasViewports) {
|
|
67975
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
67976
|
+
}
|
|
67977
|
+
return { x, y, width: width - x, height: height - y };
|
|
67909
67978
|
}
|
|
67910
67979
|
}
|
|
67911
67980
|
|
|
@@ -68902,7 +68971,7 @@ class BottomBar extends Component {
|
|
|
68902
68971
|
draggedItemId: sheetId,
|
|
68903
68972
|
initialMousePosition: event.clientX,
|
|
68904
68973
|
items: sheets,
|
|
68905
|
-
|
|
68974
|
+
scrollableContainerEl: this.sheetListRef.el,
|
|
68906
68975
|
onDragEnd: (sheetId, finalIndex) => this.onDragEnd(sheetId, finalIndex),
|
|
68907
68976
|
});
|
|
68908
68977
|
}
|
|
@@ -74997,6 +75066,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
|
|
|
74997
75066
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
74998
75067
|
|
|
74999
75068
|
|
|
75000
|
-
__info__.version = "18.1.
|
|
75001
|
-
__info__.date = "2025-
|
|
75002
|
-
__info__.hash = "
|
|
75069
|
+
__info__.version = "18.1.7";
|
|
75070
|
+
__info__.date = "2025-02-10T09:00:28.556Z";
|
|
75071
|
+
__info__.hash = "338d8a1";
|