@odoo/o-spreadsheet 19.0.11 → 19.0.15
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 +485 -377
- package/dist/o-spreadsheet.d.ts +46 -31
- package/dist/o-spreadsheet.esm.js +485 -377
- package/dist/o-spreadsheet.iife.js +485 -377
- package/dist/o-spreadsheet.iife.min.js +419 -430
- package/dist/o_spreadsheet.css +390 -0
- package/dist/o_spreadsheet.xml +80 -48
- package/package.json +4 -3
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 19.0.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.0.15
|
|
6
|
+
* @date 2025-12-26T10:19:23.408Z
|
|
7
|
+
* @hash fe625c9
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -182,7 +182,6 @@
|
|
|
182
182
|
"REDO",
|
|
183
183
|
"ADD_MERGE",
|
|
184
184
|
"REMOVE_MERGE",
|
|
185
|
-
"DUPLICATE_SHEET",
|
|
186
185
|
"UPDATE_LOCALE",
|
|
187
186
|
"ADD_PIVOT",
|
|
188
187
|
"UPDATE_PIVOT",
|
|
@@ -1895,21 +1894,25 @@
|
|
|
1895
1894
|
function profilesContainsZone(profilesStartingPosition, profiles, zone) {
|
|
1896
1895
|
const leftValue = zone.left;
|
|
1897
1896
|
const rightValue = zone.right;
|
|
1898
|
-
const topValue = zone.top;
|
|
1899
|
-
const bottomValue = zone.bottom + 1;
|
|
1900
1897
|
const leftIndex = binaryPredecessorSearch(profilesStartingPosition, leftValue, 0);
|
|
1901
|
-
const rightIndex =
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1898
|
+
const rightIndex = rightValue === undefined
|
|
1899
|
+
? profilesStartingPosition.length - 1
|
|
1900
|
+
: binaryPredecessorSearch(profilesStartingPosition, rightValue, leftIndex);
|
|
1901
|
+
/**
|
|
1902
|
+
* The `profilesStartingPosition` array always contains at least the value `0` at its first position,
|
|
1903
|
+
* ensuring that applying `binaryPredecessorSearch` will always return a valid index.
|
|
1904
|
+
* Therefore, it is not necessary to check if the result of `binaryPredecessorSearch` equals `-1`.
|
|
1905
|
+
*/
|
|
1906
|
+
const topValue = zone.top;
|
|
1907
|
+
const bottomValue = zone.bottom === undefined ? undefined : zone.bottom + 1;
|
|
1905
1908
|
for (let i = leftIndex; i <= rightIndex; i++) {
|
|
1906
1909
|
const profile = profiles.get(profilesStartingPosition[i]);
|
|
1907
|
-
const topPredIndex = binaryPredecessorSearch(profile, topValue, 0
|
|
1908
|
-
const bottomSuccIndex = binarySuccessorSearch(profile, bottomValue, 0, true);
|
|
1910
|
+
const topPredIndex = binaryPredecessorSearch(profile, topValue, 0);
|
|
1909
1911
|
if (topPredIndex === -1 || topPredIndex % 2 !== 0) {
|
|
1910
1912
|
return false;
|
|
1911
1913
|
}
|
|
1912
|
-
|
|
1914
|
+
const bottomSuccIndex = bottomValue === undefined ? profile.length : binarySuccessorSearch(profile, bottomValue, 0);
|
|
1915
|
+
if (topPredIndex + 1 !== bottomSuccIndex) {
|
|
1913
1916
|
return false;
|
|
1914
1917
|
}
|
|
1915
1918
|
}
|
|
@@ -6595,17 +6598,41 @@
|
|
|
6595
6598
|
const today = DateTime.now();
|
|
6596
6599
|
switch (dateValue) {
|
|
6597
6600
|
case "today":
|
|
6598
|
-
return jsDateToNumber(today);
|
|
6599
|
-
case "yesterday":
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6601
|
+
return Math.floor(jsDateToNumber(today));
|
|
6602
|
+
case "yesterday": {
|
|
6603
|
+
today.setDate(today.getDate() - 1);
|
|
6604
|
+
return Math.floor(jsDateToNumber(today));
|
|
6605
|
+
}
|
|
6606
|
+
case "tomorrow": {
|
|
6607
|
+
today.setDate(today.getDate() + 1);
|
|
6608
|
+
return Math.floor(jsDateToNumber(today));
|
|
6609
|
+
}
|
|
6603
6610
|
case "lastWeek":
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6611
|
+
today.setDate(today.getDate() - 6);
|
|
6612
|
+
return Math.floor(jsDateToNumber(today));
|
|
6613
|
+
case "lastMonth": {
|
|
6614
|
+
const lastMonth = today.getMonth() === 0 ? 11 : today.getMonth() - 1;
|
|
6615
|
+
const dateInLastMonth = new DateTime(today.getFullYear(), lastMonth, 1);
|
|
6616
|
+
if (today.getDate() > getDaysInMonth(dateInLastMonth)) {
|
|
6617
|
+
today.setDate(1);
|
|
6618
|
+
}
|
|
6619
|
+
else {
|
|
6620
|
+
today.setDate(today.getDate() + 1);
|
|
6621
|
+
today.setMonth(today.getMonth() - 1);
|
|
6622
|
+
}
|
|
6623
|
+
return Math.floor(jsDateToNumber(today));
|
|
6624
|
+
}
|
|
6607
6625
|
case "lastYear":
|
|
6608
|
-
|
|
6626
|
+
// Handle leap year case
|
|
6627
|
+
if (today.getMonth() === 1 && today.getDate() === 29) {
|
|
6628
|
+
today.setDate(28);
|
|
6629
|
+
today.setFullYear(today.getFullYear() - 1);
|
|
6630
|
+
}
|
|
6631
|
+
else {
|
|
6632
|
+
today.setDate(today.getDate() + 1);
|
|
6633
|
+
today.setFullYear(today.getFullYear() - 1);
|
|
6634
|
+
}
|
|
6635
|
+
return Math.floor(jsDateToNumber(today));
|
|
6609
6636
|
}
|
|
6610
6637
|
}
|
|
6611
6638
|
/** Get all the dates values of a criterion converted to numbers, converting date values such as "today" to actual dates */
|
|
@@ -6778,67 +6805,6 @@
|
|
|
6778
6805
|
return sheetName !== undefined ? `${getCanonicalSymbolName(sheetName)}!${xc}` : xc;
|
|
6779
6806
|
}
|
|
6780
6807
|
|
|
6781
|
-
function createDefaultRows(rowNumber) {
|
|
6782
|
-
const rows = [];
|
|
6783
|
-
for (let i = 0; i < rowNumber; i++) {
|
|
6784
|
-
const row = {
|
|
6785
|
-
cells: {},
|
|
6786
|
-
};
|
|
6787
|
-
rows.push(row);
|
|
6788
|
-
}
|
|
6789
|
-
return rows;
|
|
6790
|
-
}
|
|
6791
|
-
function moveHeaderIndexesOnHeaderAddition(indexHeaderAdded, numberAdded, headers) {
|
|
6792
|
-
return headers.map((header) => {
|
|
6793
|
-
if (header >= indexHeaderAdded) {
|
|
6794
|
-
return header + numberAdded;
|
|
6795
|
-
}
|
|
6796
|
-
return header;
|
|
6797
|
-
});
|
|
6798
|
-
}
|
|
6799
|
-
function moveHeaderIndexesOnHeaderDeletion(deletedHeaders, headers) {
|
|
6800
|
-
deletedHeaders = [...deletedHeaders].sort((a, b) => b - a);
|
|
6801
|
-
return headers
|
|
6802
|
-
.map((header) => {
|
|
6803
|
-
for (const deletedHeader of deletedHeaders) {
|
|
6804
|
-
if (header > deletedHeader) {
|
|
6805
|
-
header--;
|
|
6806
|
-
}
|
|
6807
|
-
else if (header === deletedHeader) {
|
|
6808
|
-
return undefined;
|
|
6809
|
-
}
|
|
6810
|
-
}
|
|
6811
|
-
return header;
|
|
6812
|
-
})
|
|
6813
|
-
.filter(isDefined);
|
|
6814
|
-
}
|
|
6815
|
-
function getNextSheetName(existingNames, baseName = "Sheet") {
|
|
6816
|
-
let i = 1;
|
|
6817
|
-
let name = `${baseName}${i}`;
|
|
6818
|
-
while (existingNames.includes(name)) {
|
|
6819
|
-
name = `${baseName}${i}`;
|
|
6820
|
-
i++;
|
|
6821
|
-
}
|
|
6822
|
-
return name;
|
|
6823
|
-
}
|
|
6824
|
-
function getDuplicateSheetName(nameToDuplicate, existingNames) {
|
|
6825
|
-
let i = 1;
|
|
6826
|
-
const baseName = _t("Copy of %s", nameToDuplicate);
|
|
6827
|
-
let name = baseName.toString();
|
|
6828
|
-
while (existingNames.includes(name)) {
|
|
6829
|
-
name = `${baseName} (${i})`;
|
|
6830
|
-
i++;
|
|
6831
|
-
}
|
|
6832
|
-
return name;
|
|
6833
|
-
}
|
|
6834
|
-
function isSheetNameEqual(name1, name2) {
|
|
6835
|
-
if (name1 === undefined || name2 === undefined) {
|
|
6836
|
-
return false;
|
|
6837
|
-
}
|
|
6838
|
-
return (getUnquotedSheetName(name1.trim().toUpperCase()) ===
|
|
6839
|
-
getUnquotedSheetName(name2.trim().toUpperCase()));
|
|
6840
|
-
}
|
|
6841
|
-
|
|
6842
6808
|
function createRange(args, getSheetSize) {
|
|
6843
6809
|
const unboundedZone = args.zone;
|
|
6844
6810
|
const zone = boundUnboundedZone(unboundedZone, getSheetSize(args.sheetId));
|
|
@@ -7086,7 +7052,7 @@
|
|
|
7086
7052
|
elements.sort((a, b) => b - a);
|
|
7087
7053
|
const groups = groupConsecutive(elements);
|
|
7088
7054
|
return (range) => {
|
|
7089
|
-
if (
|
|
7055
|
+
if (range.sheetId !== cmd.sheetId) {
|
|
7090
7056
|
return { changeType: "NONE" };
|
|
7091
7057
|
}
|
|
7092
7058
|
let newRange = range;
|
|
@@ -7293,6 +7259,69 @@
|
|
|
7293
7259
|
return results.map((r) => r.elem);
|
|
7294
7260
|
}
|
|
7295
7261
|
|
|
7262
|
+
function createDefaultRows(rowNumber) {
|
|
7263
|
+
const rows = [];
|
|
7264
|
+
for (let i = 0; i < rowNumber; i++) {
|
|
7265
|
+
const row = {
|
|
7266
|
+
cells: {},
|
|
7267
|
+
};
|
|
7268
|
+
rows.push(row);
|
|
7269
|
+
}
|
|
7270
|
+
return rows;
|
|
7271
|
+
}
|
|
7272
|
+
function moveHeaderIndexesOnHeaderAddition(indexHeaderAdded, numberAdded, headers) {
|
|
7273
|
+
return headers.map((header) => {
|
|
7274
|
+
if (header >= indexHeaderAdded) {
|
|
7275
|
+
return header + numberAdded;
|
|
7276
|
+
}
|
|
7277
|
+
return header;
|
|
7278
|
+
});
|
|
7279
|
+
}
|
|
7280
|
+
function moveHeaderIndexesOnHeaderDeletion(deletedHeaders, headers) {
|
|
7281
|
+
deletedHeaders = [...deletedHeaders].sort((a, b) => b - a);
|
|
7282
|
+
return headers
|
|
7283
|
+
.map((header) => {
|
|
7284
|
+
for (const deletedHeader of deletedHeaders) {
|
|
7285
|
+
if (header > deletedHeader) {
|
|
7286
|
+
header--;
|
|
7287
|
+
}
|
|
7288
|
+
else if (header === deletedHeader) {
|
|
7289
|
+
return undefined;
|
|
7290
|
+
}
|
|
7291
|
+
}
|
|
7292
|
+
return header;
|
|
7293
|
+
})
|
|
7294
|
+
.filter(isDefined);
|
|
7295
|
+
}
|
|
7296
|
+
function getNextSheetName(existingNames, baseName = "Sheet") {
|
|
7297
|
+
let i = 1;
|
|
7298
|
+
let name = `${baseName}${i}`;
|
|
7299
|
+
while (existingNames.includes(name)) {
|
|
7300
|
+
name = `${baseName}${i}`;
|
|
7301
|
+
i++;
|
|
7302
|
+
}
|
|
7303
|
+
return name;
|
|
7304
|
+
}
|
|
7305
|
+
function getDuplicateSheetName(nameToDuplicate, existingNames) {
|
|
7306
|
+
let i = 1;
|
|
7307
|
+
const baseName = _t("Copy of %s", nameToDuplicate);
|
|
7308
|
+
let name = baseName.toString();
|
|
7309
|
+
while (existingNames.includes(name)) {
|
|
7310
|
+
name = `${baseName} (${i})`;
|
|
7311
|
+
i++;
|
|
7312
|
+
}
|
|
7313
|
+
return name;
|
|
7314
|
+
}
|
|
7315
|
+
const toStandardizedSheetName = memoize(function toStandardizedSheetName(name) {
|
|
7316
|
+
return getUnquotedSheetName(name.trim().toUpperCase());
|
|
7317
|
+
});
|
|
7318
|
+
function isSheetNameEqual(name1, name2) {
|
|
7319
|
+
if (name1 === undefined || name2 === undefined) {
|
|
7320
|
+
return false;
|
|
7321
|
+
}
|
|
7322
|
+
return toStandardizedSheetName(name1) === toStandardizedSheetName(name2);
|
|
7323
|
+
}
|
|
7324
|
+
|
|
7296
7325
|
function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
|
|
7297
7326
|
return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
|
|
7298
7327
|
}
|
|
@@ -23878,6 +23907,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
23878
23907
|
}));
|
|
23879
23908
|
}
|
|
23880
23909
|
function getTreeMapColorScale(tree, coloringOption) {
|
|
23910
|
+
if (tree.length === 0) {
|
|
23911
|
+
return undefined;
|
|
23912
|
+
}
|
|
23881
23913
|
const treeNodesByLevel = pyramidizeTree(tree);
|
|
23882
23914
|
const nodes = treeNodesByLevel[treeNodesByLevel.length - 1];
|
|
23883
23915
|
const minValue = Math.min(...nodes.map((node) => node.value));
|
|
@@ -25563,11 +25595,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
25563
25595
|
// we have to add the canvas to the DOM otherwise it won't be rendered
|
|
25564
25596
|
document.body.append(div);
|
|
25565
25597
|
if ("chartJsConfig" in runtime) {
|
|
25598
|
+
const extensionsLoaded = areChartJSExtensionsLoaded();
|
|
25599
|
+
if (!extensionsLoaded) {
|
|
25600
|
+
registerChartJSExtensions();
|
|
25601
|
+
}
|
|
25566
25602
|
const config = deepCopy(runtime.chartJsConfig);
|
|
25567
25603
|
config.plugins = [backgroundColorChartJSPlugin];
|
|
25568
25604
|
const chart = new window.Chart(canvas, config);
|
|
25569
25605
|
imageContent = chart.toBase64Image();
|
|
25570
25606
|
chart.destroy();
|
|
25607
|
+
if (!extensionsLoaded) {
|
|
25608
|
+
unregisterChartJsExtensions();
|
|
25609
|
+
}
|
|
25571
25610
|
}
|
|
25572
25611
|
else if (type === "scorecard") {
|
|
25573
25612
|
const design = getScorecardConfiguration(figure, runtime);
|
|
@@ -25597,11 +25636,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
25597
25636
|
document.body.append(div);
|
|
25598
25637
|
let chartBlob = null;
|
|
25599
25638
|
if ("chartJsConfig" in runtime) {
|
|
25639
|
+
const extensionsLoaded = areChartJSExtensionsLoaded();
|
|
25640
|
+
if (!extensionsLoaded) {
|
|
25641
|
+
registerChartJSExtensions();
|
|
25642
|
+
}
|
|
25600
25643
|
const config = deepCopy(runtime.chartJsConfig);
|
|
25601
25644
|
config.plugins = [backgroundColorChartJSPlugin];
|
|
25602
25645
|
const chart = new window.Chart(canvas, config);
|
|
25603
25646
|
chartBlob = await new Promise((resolve) => canvas.toBlob(resolve, "image/png"));
|
|
25604
25647
|
chart.destroy();
|
|
25648
|
+
if (!extensionsLoaded) {
|
|
25649
|
+
unregisterChartJsExtensions();
|
|
25650
|
+
}
|
|
25605
25651
|
}
|
|
25606
25652
|
else if (type === "scorecard") {
|
|
25607
25653
|
const design = getScorecardConfiguration(figure, runtime);
|
|
@@ -27727,29 +27773,19 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27727
27773
|
}
|
|
27728
27774
|
resetAxisLimits(chartId, limits) {
|
|
27729
27775
|
for (const axisId of ZOOMABLE_AXIS_IDS) {
|
|
27730
|
-
if (limits
|
|
27731
|
-
|
|
27732
|
-
this.originalAxisLimits[chartId]
|
|
27733
|
-
|
|
27734
|
-
|
|
27735
|
-
};
|
|
27736
|
-
}
|
|
27737
|
-
this.originalAxisLimits[chartId][axisId]["min"] = limits[axisId].min;
|
|
27738
|
-
this.originalAxisLimits[chartId][axisId]["max"] = limits[axisId].max;
|
|
27776
|
+
if (limits[axisId]) {
|
|
27777
|
+
this.originalAxisLimits[chartId] = {
|
|
27778
|
+
...this.originalAxisLimits[chartId],
|
|
27779
|
+
[axisId]: { ...limits[axisId] },
|
|
27780
|
+
};
|
|
27739
27781
|
}
|
|
27740
|
-
else {
|
|
27741
|
-
|
|
27742
|
-
delete this.originalAxisLimits[chartId][axisId];
|
|
27743
|
-
}
|
|
27782
|
+
else if (this.originalAxisLimits[chartId]?.[axisId]) {
|
|
27783
|
+
delete this.originalAxisLimits[chartId][axisId];
|
|
27744
27784
|
}
|
|
27745
27785
|
}
|
|
27746
27786
|
return "noStateChange";
|
|
27747
27787
|
}
|
|
27748
27788
|
updateAxisLimits(chartId, limits) {
|
|
27749
|
-
if (limits === undefined) {
|
|
27750
|
-
delete this.currentAxesLimits[chartId];
|
|
27751
|
-
return "noStateChange";
|
|
27752
|
-
}
|
|
27753
27789
|
let { min, max } = limits;
|
|
27754
27790
|
if (min > max) {
|
|
27755
27791
|
[min, max] = [max, min];
|
|
@@ -27765,26 +27801,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27765
27801
|
* for the current trend line axes.
|
|
27766
27802
|
*/
|
|
27767
27803
|
updateTrendLineConfiguration(chartId) {
|
|
27768
|
-
if (!this.originalAxisLimits[chartId]) {
|
|
27804
|
+
if (!this.originalAxisLimits[chartId]?.x || !this.currentAxesLimits[chartId]?.x) {
|
|
27769
27805
|
return "noStateChange";
|
|
27770
27806
|
}
|
|
27771
27807
|
const chartLimits = this.originalAxisLimits[chartId].x;
|
|
27772
|
-
if (chartLimits === undefined) {
|
|
27773
|
-
return "noStateChange";
|
|
27774
|
-
}
|
|
27775
27808
|
for (const axisId of TREND_LINE_AXES_IDS) {
|
|
27776
27809
|
if (!this.originalAxisLimits[chartId][axisId]) {
|
|
27777
27810
|
continue;
|
|
27778
27811
|
}
|
|
27779
|
-
if (!this.currentAxesLimits[chartId]?.[axisId]) {
|
|
27780
|
-
this.currentAxesLimits[chartId] = {
|
|
27781
|
-
...this.currentAxesLimits[chartId],
|
|
27782
|
-
[axisId]: {},
|
|
27783
|
-
};
|
|
27784
|
-
}
|
|
27785
|
-
if (this.currentAxesLimits[chartId]?.x === undefined) {
|
|
27786
|
-
return "noStateChange";
|
|
27787
|
-
}
|
|
27788
27812
|
const realRange = chartLimits.max - chartLimits.min;
|
|
27789
27813
|
const trendingLimits = this.originalAxisLimits[chartId][axisId];
|
|
27790
27814
|
const trendingRange = trendingLimits.max - trendingLimits.min;
|
|
@@ -27792,8 +27816,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27792
27816
|
const intercept = trendingLimits.min - chartLimits.min * slope;
|
|
27793
27817
|
const newXMin = this.currentAxesLimits[chartId].x.min;
|
|
27794
27818
|
const newXMax = this.currentAxesLimits[chartId].x.max;
|
|
27795
|
-
this.currentAxesLimits[chartId][axisId]
|
|
27796
|
-
|
|
27819
|
+
this.currentAxesLimits[chartId][axisId] = {
|
|
27820
|
+
min: newXMin * slope + intercept,
|
|
27821
|
+
max: newXMax * slope + intercept,
|
|
27822
|
+
};
|
|
27797
27823
|
}
|
|
27798
27824
|
return "noStateChange";
|
|
27799
27825
|
}
|
|
@@ -27862,8 +27888,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27862
27888
|
hasLinearScale;
|
|
27863
27889
|
isBarChart;
|
|
27864
27890
|
chartId = "";
|
|
27865
|
-
datasetBoundaries = {
|
|
27891
|
+
datasetBoundaries = { min: 0, max: 0 };
|
|
27866
27892
|
removeEventListeners = () => { };
|
|
27893
|
+
isMasterChartAllowed = false;
|
|
27867
27894
|
setup() {
|
|
27868
27895
|
this.store = useStore(ZoomableChartStore);
|
|
27869
27896
|
super.setup();
|
|
@@ -27879,12 +27906,19 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27879
27906
|
height:${height};
|
|
27880
27907
|
`;
|
|
27881
27908
|
}
|
|
27909
|
+
get masterChartContainerStyle() {
|
|
27910
|
+
const runtime = this.env.model.getters.getChartRuntime(this.props.chartId);
|
|
27911
|
+
if (runtime && !runtime.chartJsConfig.data.datasets.some((ds) => ds.data.length > 1)) {
|
|
27912
|
+
return "opacity: 0.3;";
|
|
27913
|
+
}
|
|
27914
|
+
return "";
|
|
27915
|
+
}
|
|
27882
27916
|
get sliceable() {
|
|
27883
27917
|
if (this.props.isFullScreen) {
|
|
27884
27918
|
return true;
|
|
27885
27919
|
}
|
|
27886
27920
|
const definition = this.env.model.getters.getChartDefinition(this.props.chartId);
|
|
27887
|
-
return ("zoomable" in definition && definition
|
|
27921
|
+
return ("zoomable" in definition && definition.zoomable) ?? false;
|
|
27888
27922
|
}
|
|
27889
27923
|
get axisOffset() {
|
|
27890
27924
|
return !this.hasLinearScale && this.isBarChart ? 0.5 : 0;
|
|
@@ -27909,15 +27943,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27909
27943
|
if (!this.sliceable) {
|
|
27910
27944
|
return chartData;
|
|
27911
27945
|
}
|
|
27912
|
-
|
|
27913
|
-
const
|
|
27914
|
-
|
|
27915
|
-
|
|
27916
|
-
|
|
27917
|
-
|
|
27918
|
-
|
|
27919
|
-
if (xAxis?.max !== undefined) {
|
|
27920
|
-
xScale.max = this.hasLinearScale ? xAxis.max : Math.floor(xAxis.max) - this.axisOffset;
|
|
27946
|
+
let x = chartData.options.scales.x;
|
|
27947
|
+
const limits = this.store.currentAxesLimits[this.chartId]?.x;
|
|
27948
|
+
if (limits) {
|
|
27949
|
+
x = {
|
|
27950
|
+
...x,
|
|
27951
|
+
...this.getStoredBoundaries(),
|
|
27952
|
+
};
|
|
27921
27953
|
}
|
|
27922
27954
|
return {
|
|
27923
27955
|
...chartData,
|
|
@@ -27925,7 +27957,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27925
27957
|
...chartData.options,
|
|
27926
27958
|
scales: {
|
|
27927
27959
|
...chartData.options.scales,
|
|
27928
|
-
x
|
|
27960
|
+
x,
|
|
27929
27961
|
},
|
|
27930
27962
|
layout: {
|
|
27931
27963
|
...chartData.options.layout,
|
|
@@ -27940,9 +27972,19 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27940
27972
|
getAxisLimitsFromDataset(chartData) {
|
|
27941
27973
|
const data = chartData.data.datasets.map((ds) => ds.data).flat();
|
|
27942
27974
|
const xValues = data.map((d, i) => (typeof d === "object" && d !== null ? d.x : i));
|
|
27943
|
-
const
|
|
27944
|
-
const
|
|
27945
|
-
return {
|
|
27975
|
+
const min = Math.min(...xValues);
|
|
27976
|
+
const max = Math.max(...xValues);
|
|
27977
|
+
return { min, max };
|
|
27978
|
+
}
|
|
27979
|
+
setMasterChartCursor(runtime) {
|
|
27980
|
+
const masterElement = this.masterChartCanvas?.el;
|
|
27981
|
+
if (runtime && !runtime.chartJsConfig.data.datasets.some((ds) => ds.data.length > 1)) {
|
|
27982
|
+
masterElement.style.cursor = "not-allowed";
|
|
27983
|
+
this.isMasterChartAllowed = false;
|
|
27984
|
+
return;
|
|
27985
|
+
}
|
|
27986
|
+
masterElement.style.cursor = "default";
|
|
27987
|
+
this.isMasterChartAllowed = true;
|
|
27946
27988
|
}
|
|
27947
27989
|
createChart(chartRuntime) {
|
|
27948
27990
|
const chartData = chartRuntime.chartJsConfig;
|
|
@@ -27954,12 +27996,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27954
27996
|
chartRuntime.chartJsConfig = updatedData;
|
|
27955
27997
|
}
|
|
27956
27998
|
super.createChart(chartRuntime);
|
|
27957
|
-
this.hasLinearScale = this.chart?.scales?.x
|
|
27999
|
+
this.hasLinearScale = this.chart?.scales?.x?.type === "linear";
|
|
27958
28000
|
if (!this.sliceable || !("masterChartConfig" in chartRuntime)) {
|
|
28001
|
+
this.isMasterChartAllowed = false;
|
|
27959
28002
|
return;
|
|
27960
28003
|
}
|
|
27961
28004
|
this.masterChart?.destroy();
|
|
27962
|
-
const masterChartCtx = this.masterChartCanvas
|
|
28005
|
+
const masterChartCtx = (this.masterChartCanvas?.el).getContext("2d");
|
|
28006
|
+
this.setMasterChartCursor(chartRuntime);
|
|
27963
28007
|
this.masterChart = new window.Chart(masterChartCtx, this.getMasterChartConfiguration(chartRuntime["masterChartConfig"]));
|
|
27964
28008
|
this.resetAxesLimits();
|
|
27965
28009
|
if (this.chart?.options) {
|
|
@@ -27968,11 +28012,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27968
28012
|
}
|
|
27969
28013
|
updateChartJs(chartRuntime) {
|
|
27970
28014
|
const chartData = chartRuntime.chartJsConfig;
|
|
27971
|
-
const
|
|
27972
|
-
if (this.datasetBoundaries.
|
|
27973
|
-
this.datasetBoundaries.xMax !== newDatasetBoundaries.xMax) {
|
|
28015
|
+
const { min, max } = this.getAxisLimitsFromDataset(chartData);
|
|
28016
|
+
if (this.datasetBoundaries.min !== min || this.datasetBoundaries.max !== max) {
|
|
27974
28017
|
this.store.clearAxisLimits(this.chartId);
|
|
27975
|
-
this.datasetBoundaries =
|
|
28018
|
+
this.datasetBoundaries = { min, max };
|
|
27976
28019
|
}
|
|
27977
28020
|
this.isBarChart = chartData?.type === "bar";
|
|
27978
28021
|
this.chartId = `${chartData.type}-${this.props.chartId}`;
|
|
@@ -27981,9 +28024,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27981
28024
|
chartRuntime.chartJsConfig = updatedData;
|
|
27982
28025
|
}
|
|
27983
28026
|
super.updateChartJs(chartRuntime);
|
|
27984
|
-
this.hasLinearScale = this.chart?.scales?.x
|
|
28027
|
+
this.hasLinearScale = this.chart?.scales?.x?.type === "linear";
|
|
27985
28028
|
if (!this.sliceable || !("masterChartConfig" in chartRuntime)) {
|
|
27986
28029
|
this.masterChart = undefined;
|
|
28030
|
+
this.isMasterChartAllowed = false;
|
|
27987
28031
|
}
|
|
27988
28032
|
else {
|
|
27989
28033
|
const masterChartConfig = this.getMasterChartConfiguration(chartRuntime["masterChartConfig"]);
|
|
@@ -27996,6 +28040,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27996
28040
|
this.masterChart.config.options = masterChartConfig.options;
|
|
27997
28041
|
this.masterChart.update();
|
|
27998
28042
|
}
|
|
28043
|
+
this.setMasterChartCursor(chartRuntime);
|
|
27999
28044
|
}
|
|
28000
28045
|
this.resetAxesLimits();
|
|
28001
28046
|
if (this.chart?.options) {
|
|
@@ -28006,18 +28051,15 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28006
28051
|
if (!this.chart) {
|
|
28007
28052
|
return;
|
|
28008
28053
|
}
|
|
28009
|
-
const
|
|
28010
|
-
if (
|
|
28054
|
+
const storedLimits = this.store.originalAxisLimits[this.chartId]?.x;
|
|
28055
|
+
if (!storedLimits) {
|
|
28011
28056
|
let scales = this.masterChart
|
|
28012
28057
|
? this.masterChart.scales
|
|
28013
28058
|
: this.chart.scales;
|
|
28014
|
-
if (!this.hasLinearScale && scales
|
|
28059
|
+
if (!this.hasLinearScale && scales.x) {
|
|
28015
28060
|
scales = {
|
|
28016
28061
|
...scales,
|
|
28017
|
-
x:
|
|
28018
|
-
min: Math.ceil(scales.x.min) - this.axisOffset,
|
|
28019
|
-
max: Math.floor(scales.x.max) + this.axisOffset,
|
|
28020
|
-
},
|
|
28062
|
+
x: this.adjustBoundaries(scales.x),
|
|
28021
28063
|
};
|
|
28022
28064
|
}
|
|
28023
28065
|
this.store.resetAxisLimits(this.chartId, scales);
|
|
@@ -28032,13 +28074,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28032
28074
|
}
|
|
28033
28075
|
updateTrendingLineAxes() {
|
|
28034
28076
|
this.store.updateTrendLineConfiguration(this.chartId);
|
|
28035
|
-
const
|
|
28077
|
+
const limits = this.store.currentAxesLimits[this.chartId];
|
|
28036
28078
|
for (const axisId of [TREND_LINE_XAXIS_ID, MOVING_AVERAGE_TREND_LINE_XAXIS_ID]) {
|
|
28037
|
-
if (!this.chart?.config
|
|
28079
|
+
if (!this.chart?.config?.options?.scales?.[axisId] || !limits?.[axisId]) {
|
|
28038
28080
|
continue;
|
|
28039
28081
|
}
|
|
28040
|
-
this.chart.config.options.scales[axisId].min =
|
|
28041
|
-
this.chart.config.options.scales[axisId].max =
|
|
28082
|
+
this.chart.config.options.scales[axisId].min = limits[axisId].min;
|
|
28083
|
+
this.chart.config.options.scales[axisId].max = limits[axisId].max;
|
|
28042
28084
|
}
|
|
28043
28085
|
}
|
|
28044
28086
|
get upperBound() {
|
|
@@ -28081,29 +28123,71 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28081
28123
|
offset +
|
|
28082
28124
|
((scale.max + 2 * offset - scale.min) * (position - left)) / (right - left));
|
|
28083
28125
|
}
|
|
28084
|
-
|
|
28126
|
+
/**
|
|
28127
|
+
* Compute min and max from the store, adjusting them if needed for non linear scales.
|
|
28128
|
+
* Getting the value from the store, we have to ensure that the values are integers for
|
|
28129
|
+
* non linear scales (bar and category). To select a bar in the chart, we have to include
|
|
28130
|
+
* the whole bar, which means that for the i-th bar, the selected min should be <= i and
|
|
28131
|
+
* the selected max should be >= i, so using the Math.floor and Math.ceil functions is
|
|
28132
|
+
* the right way to do it.
|
|
28133
|
+
* Sometimes, we can get a minimal value > the maximal value, which arise when the user
|
|
28134
|
+
* select a very small area in the master chart, and hasn't selected the middle of a bar
|
|
28135
|
+
* or a group of bars (in case of more than one data series).
|
|
28136
|
+
* Assuming we have to select the middle of a bar/a groupe of bars, we will reject the
|
|
28137
|
+
* coming value afterward. In this case, we do not update the chart because it would lead
|
|
28138
|
+
* to an empty chart.
|
|
28139
|
+
*/
|
|
28140
|
+
getStoredBoundaries() {
|
|
28141
|
+
let { min, max } = this.store.currentAxesLimits[this.chartId].x;
|
|
28085
28142
|
if (!this.hasLinearScale) {
|
|
28086
|
-
|
|
28087
|
-
|
|
28143
|
+
min = Math.ceil(min);
|
|
28144
|
+
max = Math.floor(max);
|
|
28088
28145
|
}
|
|
28089
|
-
|
|
28090
|
-
|
|
28091
|
-
|
|
28146
|
+
return { min, max };
|
|
28147
|
+
}
|
|
28148
|
+
/**
|
|
28149
|
+
* Adjust the min and max values of an axis if needed for non linear scales.
|
|
28150
|
+
* Here, after rounding (see docstring of getStoredBoundaries), we adjust the min by
|
|
28151
|
+
* substracting the axis offset, and we add it to the max, because when computing from the
|
|
28152
|
+
* scale, chartJs use integer values as the limits for non linear scales. If we have a min
|
|
28153
|
+
* value of 1, it means we want to start displaying from 0.5, and if we have a max value of
|
|
28154
|
+
* 4, it means we want to display until 4.5.
|
|
28155
|
+
* Here, we don't have to check if min > max because we are computing from the scale, and
|
|
28156
|
+
* chartJs ensures that this won't happen, even after our adjustments.
|
|
28157
|
+
*/
|
|
28158
|
+
adjustBoundaries({ min, max }) {
|
|
28159
|
+
if (!this.hasLinearScale) {
|
|
28160
|
+
min = Math.ceil(min) - this.axisOffset;
|
|
28161
|
+
max = Math.floor(max) + this.axisOffset;
|
|
28162
|
+
}
|
|
28163
|
+
return { min, max };
|
|
28164
|
+
}
|
|
28165
|
+
updateAxisLimits(xMin, xMax) {
|
|
28166
|
+
if (xMin === xMax) {
|
|
28167
|
+
return;
|
|
28168
|
+
}
|
|
28169
|
+
if (!this.chart) {
|
|
28170
|
+
return;
|
|
28092
28171
|
}
|
|
28093
28172
|
this.store.updateAxisLimits(this.chartId, { min: xMin, max: xMax });
|
|
28094
|
-
this.
|
|
28173
|
+
const { min, max } = this.getStoredBoundaries();
|
|
28174
|
+
if (max > min || (this.isBarChart && max === min)) {
|
|
28175
|
+
this.chart.config.options.scales.x.min = min;
|
|
28176
|
+
this.chart.config.options.scales.x.max = max;
|
|
28177
|
+
this.updateTrendingLineAxes();
|
|
28178
|
+
this.chart.update();
|
|
28179
|
+
}
|
|
28095
28180
|
this.masterChart?.update();
|
|
28096
|
-
this.chart?.update();
|
|
28097
28181
|
}
|
|
28098
|
-
|
|
28182
|
+
onMasterChartPointerDown(ev) {
|
|
28099
28183
|
this.removeEventListeners();
|
|
28100
28184
|
const position = ev.offsetX;
|
|
28101
28185
|
if (!this.masterChart?.chartArea || !this.chart?.scales?.x) {
|
|
28102
28186
|
return;
|
|
28103
28187
|
}
|
|
28104
28188
|
const { left, right, top, bottom } = this.masterChart.chartArea;
|
|
28105
|
-
const
|
|
28106
|
-
const
|
|
28189
|
+
const upperBound = this.upperBound ?? right;
|
|
28190
|
+
const lowerBound = this.lowerBound ?? left;
|
|
28107
28191
|
if (position < left - 5 || position > right + 5 || ev.offsetY < top || ev.offsetY > bottom) {
|
|
28108
28192
|
return;
|
|
28109
28193
|
}
|
|
@@ -28111,8 +28195,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28111
28195
|
ev.stopPropagation();
|
|
28112
28196
|
let startingPositionOnChart, windowSize, startX;
|
|
28113
28197
|
const startingEventPosition = ev.clientX - (this.masterChartCanvas.el?.getBoundingClientRect().left ?? 0);
|
|
28114
|
-
if ((
|
|
28115
|
-
|
|
28198
|
+
if ((lowerBound !== left || upperBound !== right) &&
|
|
28199
|
+
position > lowerBound + 5 &&
|
|
28200
|
+
position < upperBound - 5) {
|
|
28201
|
+
startingPositionOnChart = ev.offsetX - lowerBound;
|
|
28116
28202
|
this.mode = "moveInMaster";
|
|
28117
28203
|
const currentLimits = this.store.currentAxesLimits[this.chartId]?.x;
|
|
28118
28204
|
windowSize =
|
|
@@ -28121,31 +28207,29 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28121
28207
|
}
|
|
28122
28208
|
else {
|
|
28123
28209
|
this.mode = "selectInMaster";
|
|
28124
|
-
if (Math.abs(position -
|
|
28125
|
-
startingPositionOnChart =
|
|
28210
|
+
if (Math.abs(position - lowerBound) < 5) {
|
|
28211
|
+
startingPositionOnChart = upperBound;
|
|
28126
28212
|
}
|
|
28127
|
-
else if (Math.abs(position -
|
|
28128
|
-
startingPositionOnChart =
|
|
28213
|
+
else if (Math.abs(position - upperBound) < 5) {
|
|
28214
|
+
startingPositionOnChart = lowerBound;
|
|
28129
28215
|
}
|
|
28130
28216
|
else {
|
|
28131
28217
|
startingPositionOnChart = clip(position, left, right);
|
|
28132
28218
|
}
|
|
28133
28219
|
startX = this.computeCoordinate(startingPositionOnChart);
|
|
28134
28220
|
}
|
|
28135
|
-
const
|
|
28136
|
-
const
|
|
28221
|
+
const storedMin = this.store.originalAxisLimits[this.chartId].x.min;
|
|
28222
|
+
const storedMax = this.store.originalAxisLimits[this.chartId].x.max;
|
|
28137
28223
|
const computeNewAxisLimits = (position) => {
|
|
28138
|
-
let xMin, xMax;
|
|
28139
|
-
const { left, right } = this.masterChart.chartArea;
|
|
28140
28224
|
if (this.mode === "moveInMaster") {
|
|
28141
|
-
|
|
28142
|
-
if (
|
|
28143
|
-
|
|
28225
|
+
let min = this.computeCoordinate(position - startingPositionOnChart);
|
|
28226
|
+
if (min < storedMin) {
|
|
28227
|
+
min = storedMin;
|
|
28144
28228
|
}
|
|
28145
|
-
else if (
|
|
28146
|
-
|
|
28229
|
+
else if (min > storedMax - windowSize) {
|
|
28230
|
+
min = storedMax - windowSize;
|
|
28147
28231
|
}
|
|
28148
|
-
|
|
28232
|
+
return { min, max: min + windowSize };
|
|
28149
28233
|
}
|
|
28150
28234
|
else if (this.mode === "selectInMaster") {
|
|
28151
28235
|
const upperBound = clip(position, left, right);
|
|
@@ -28154,54 +28238,52 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28154
28238
|
if (startX === undefined || endX === undefined) {
|
|
28155
28239
|
return {};
|
|
28156
28240
|
}
|
|
28157
|
-
|
|
28158
|
-
|
|
28241
|
+
return {
|
|
28242
|
+
min: Math.min(startX, endX),
|
|
28243
|
+
max: Math.max(startX, endX),
|
|
28244
|
+
};
|
|
28159
28245
|
}
|
|
28160
28246
|
}
|
|
28161
|
-
return {
|
|
28247
|
+
return {};
|
|
28162
28248
|
};
|
|
28163
|
-
const
|
|
28249
|
+
const onMasterChartDrag = (ev) => {
|
|
28164
28250
|
const position = ev.clientX - (this.masterChartCanvas.el?.getBoundingClientRect().left ?? 0);
|
|
28165
28251
|
if (Math.abs(position - startingEventPosition) < 5) {
|
|
28166
28252
|
return;
|
|
28167
28253
|
}
|
|
28168
|
-
const { min
|
|
28169
|
-
if (
|
|
28170
|
-
this.updateAxisLimits(
|
|
28254
|
+
const { min, max } = computeNewAxisLimits(position);
|
|
28255
|
+
if (min !== undefined && max !== undefined) {
|
|
28256
|
+
this.updateAxisLimits(min, max);
|
|
28171
28257
|
}
|
|
28172
28258
|
};
|
|
28173
|
-
const
|
|
28259
|
+
const onMasterChartPointerUp = (ev) => {
|
|
28174
28260
|
this.removeEventListeners();
|
|
28175
|
-
|
|
28176
|
-
if (
|
|
28177
|
-
|
|
28178
|
-
|
|
28179
|
-
|
|
28180
|
-
|
|
28181
|
-
|
|
28182
|
-
|
|
28183
|
-
}
|
|
28184
|
-
else {
|
|
28185
|
-
xMin = Math.ceil(xMin) - this.axisOffset;
|
|
28186
|
-
xMax = Math.floor(xMax) + this.axisOffset;
|
|
28187
|
-
}
|
|
28188
|
-
}
|
|
28189
|
-
this.updateAxisLimits(xMin, xMax);
|
|
28261
|
+
let { min, max } = this.chart.scales.x;
|
|
28262
|
+
if (!this.hasLinearScale) {
|
|
28263
|
+
if (this.mode === "moveInMaster") {
|
|
28264
|
+
min = Math.round(min) - this.axisOffset;
|
|
28265
|
+
max = min + windowSize;
|
|
28266
|
+
}
|
|
28267
|
+
else {
|
|
28268
|
+
({ min, max } = this.adjustBoundaries({ min, max }));
|
|
28190
28269
|
}
|
|
28191
28270
|
}
|
|
28271
|
+
this.updateAxisLimits(min, max);
|
|
28192
28272
|
this.mode = undefined;
|
|
28193
28273
|
};
|
|
28194
28274
|
this.removeEventListeners = () => {
|
|
28195
|
-
window.removeEventListener("pointermove",
|
|
28196
|
-
window.removeEventListener("pointerup",
|
|
28275
|
+
window.removeEventListener("pointermove", onMasterChartDrag, true);
|
|
28276
|
+
window.removeEventListener("pointerup", onMasterChartPointerUp, true);
|
|
28197
28277
|
};
|
|
28198
|
-
window.addEventListener("pointermove",
|
|
28199
|
-
window.addEventListener("pointerup",
|
|
28278
|
+
window.addEventListener("pointermove", onMasterChartDrag, true);
|
|
28279
|
+
window.addEventListener("pointerup", onMasterChartPointerUp, true);
|
|
28200
28280
|
}
|
|
28201
|
-
|
|
28202
|
-
const { offsetX: x, offsetY: y } = ev;
|
|
28281
|
+
onMasterChartPointerMove(ev) {
|
|
28282
|
+
const { offsetX: x, offsetY: y, target } = ev;
|
|
28283
|
+
if (!target || !this.isMasterChartAllowed) {
|
|
28284
|
+
return;
|
|
28285
|
+
}
|
|
28203
28286
|
if (this.mode === undefined) {
|
|
28204
|
-
const target = ev.target;
|
|
28205
28287
|
if (!this.masterChart?.chartArea) {
|
|
28206
28288
|
target["style"].cursor = "default";
|
|
28207
28289
|
return;
|
|
@@ -28223,14 +28305,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28223
28305
|
}
|
|
28224
28306
|
}
|
|
28225
28307
|
}
|
|
28226
|
-
|
|
28308
|
+
onMasterChartMouseLeave(ev) {
|
|
28227
28309
|
const target = ev.target;
|
|
28228
|
-
if (!target) {
|
|
28310
|
+
if (!target || !this.isMasterChartAllowed) {
|
|
28229
28311
|
return;
|
|
28230
28312
|
}
|
|
28231
28313
|
target["style"].cursor = "default";
|
|
28232
28314
|
}
|
|
28233
|
-
|
|
28315
|
+
onMasterChartDoubleClick(ev) {
|
|
28234
28316
|
this.mode = undefined;
|
|
28235
28317
|
const position = ev.offsetX;
|
|
28236
28318
|
if (!this.masterChart?.chartArea || !this.chart?.scales.x) {
|
|
@@ -28247,33 +28329,25 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28247
28329
|
}
|
|
28248
28330
|
ev.preventDefault();
|
|
28249
28331
|
ev.stopPropagation();
|
|
28250
|
-
let { min
|
|
28332
|
+
let { min, max } = this.store.currentAxesLimits[this.chartId]?.x ?? this.chart.scales.x;
|
|
28251
28333
|
const originalAxisLimits = this.store.originalAxisLimits[this.chartId].x;
|
|
28252
28334
|
if (!originalAxisLimits) {
|
|
28253
28335
|
return;
|
|
28254
28336
|
}
|
|
28255
|
-
let originalXMin = originalAxisLimits.min;
|
|
28256
|
-
let originalXMax = originalAxisLimits.max;
|
|
28257
|
-
if (this.hasLinearScale) {
|
|
28258
|
-
originalXMin = Math.ceil(originalXMin) - this.axisOffset;
|
|
28259
|
-
originalXMax = Math.floor(originalXMax) + this.axisOffset;
|
|
28260
|
-
}
|
|
28261
28337
|
if (Math.abs(position - lowerBound) < 5) {
|
|
28262
|
-
|
|
28263
|
-
xMin = originalXMin;
|
|
28338
|
+
min = originalAxisLimits.min;
|
|
28264
28339
|
}
|
|
28265
28340
|
else if (Math.abs(position - upperBound) < 5) {
|
|
28266
|
-
|
|
28341
|
+
max = originalAxisLimits.max;
|
|
28267
28342
|
}
|
|
28268
28343
|
else if (lowerBound < position && position < upperBound) {
|
|
28269
|
-
|
|
28270
|
-
|
|
28271
|
-
xMax = originalXMax;
|
|
28344
|
+
min = originalAxisLimits.min;
|
|
28345
|
+
max = originalAxisLimits.max;
|
|
28272
28346
|
}
|
|
28273
28347
|
else {
|
|
28274
28348
|
return;
|
|
28275
28349
|
}
|
|
28276
|
-
this.updateAxisLimits(
|
|
28350
|
+
this.updateAxisLimits(min, max);
|
|
28277
28351
|
}
|
|
28278
28352
|
}
|
|
28279
28353
|
|
|
@@ -31376,7 +31450,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
31376
31450
|
return query.replaceAll(/([a-zA-Z0-9]+):([a-zA-Z0-9]+)/g, "NAMESPACE" + "$1" + "NAMESPACE" + "$2");
|
|
31377
31451
|
}
|
|
31378
31452
|
|
|
31379
|
-
function getChartMenuActions(figureId,
|
|
31453
|
+
function getChartMenuActions(figureId, env) {
|
|
31380
31454
|
const chartId = env.model.getters.getChartIdFromFigureId(figureId);
|
|
31381
31455
|
if (!chartId) {
|
|
31382
31456
|
return [];
|
|
@@ -31396,11 +31470,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
31396
31470
|
getCutMenuItem(figureId, env),
|
|
31397
31471
|
getCopyAsImageMenuItem(figureId, env),
|
|
31398
31472
|
getDownloadChartMenuItem(figureId, env),
|
|
31399
|
-
getDeleteMenuItem(figureId,
|
|
31473
|
+
getDeleteMenuItem(figureId, env),
|
|
31400
31474
|
];
|
|
31401
31475
|
return createActions(menuItemSpecs).filter((action) => env.model.getters.isReadonly() ? action.isReadonlyAllowed : true);
|
|
31402
31476
|
}
|
|
31403
|
-
function getImageMenuActions(figureId,
|
|
31477
|
+
function getImageMenuActions(figureId, env) {
|
|
31404
31478
|
const menuItemSpecs = [
|
|
31405
31479
|
getCopyMenuItem(figureId, env, _t("Image copied to clipboard")),
|
|
31406
31480
|
getCutMenuItem(figureId, env),
|
|
@@ -31443,11 +31517,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
31443
31517
|
},
|
|
31444
31518
|
icon: "o-spreadsheet-Icon.DOWNLOAD",
|
|
31445
31519
|
},
|
|
31446
|
-
getDeleteMenuItem(figureId,
|
|
31520
|
+
getDeleteMenuItem(figureId, env),
|
|
31447
31521
|
];
|
|
31448
31522
|
return createActions(menuItemSpecs);
|
|
31449
31523
|
}
|
|
31450
|
-
function getCarouselMenuActions(figureId,
|
|
31524
|
+
function getCarouselMenuActions(figureId, env) {
|
|
31451
31525
|
const isChartSelected = (env) => env.model.getters.getSelectedCarouselItem(figureId)?.type === "chart";
|
|
31452
31526
|
const menuItemSpecs = [
|
|
31453
31527
|
{
|
|
@@ -31466,7 +31540,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
31466
31540
|
},
|
|
31467
31541
|
{ ...getCutMenuItem(figureId, env), name: _t("Cut carousel") },
|
|
31468
31542
|
{
|
|
31469
|
-
...getDeleteMenuItem(figureId,
|
|
31543
|
+
...getDeleteMenuItem(figureId, env),
|
|
31470
31544
|
name: _t("Delete carousel"),
|
|
31471
31545
|
separator: true,
|
|
31472
31546
|
},
|
|
@@ -31609,7 +31683,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
31609
31683
|
isReadonlyAllowed: true,
|
|
31610
31684
|
};
|
|
31611
31685
|
}
|
|
31612
|
-
function getDeleteMenuItem(figureId,
|
|
31686
|
+
function getDeleteMenuItem(figureId, env) {
|
|
31613
31687
|
return {
|
|
31614
31688
|
id: "delete",
|
|
31615
31689
|
name: _t("Delete"),
|
|
@@ -31618,7 +31692,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
31618
31692
|
sheetId: env.model.getters.getActiveSheetId(),
|
|
31619
31693
|
figureId,
|
|
31620
31694
|
});
|
|
31621
|
-
onFigureDeleted();
|
|
31622
31695
|
},
|
|
31623
31696
|
icon: "o-spreadsheet-Icon.TRASH",
|
|
31624
31697
|
};
|
|
@@ -32431,7 +32504,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32431
32504
|
this.menuState.isOpen = true;
|
|
32432
32505
|
this.menuState.anchorRect = getBoundingRectAsPOJO(ev.currentTarget);
|
|
32433
32506
|
const figureId = this.env.model.getters.getFigureIdFromChartId(this.props.chartId);
|
|
32434
|
-
this.menuState.menuItems = getChartMenuActions(figureId,
|
|
32507
|
+
this.menuState.menuItems = getChartMenuActions(figureId, this.env);
|
|
32435
32508
|
}
|
|
32436
32509
|
get fullScreenMenuItem() {
|
|
32437
32510
|
if (!this.props.hasFullScreenButton) {
|
|
@@ -32458,7 +32531,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32458
32531
|
static template = "o-spreadsheet-CarouselFigure";
|
|
32459
32532
|
static props = {
|
|
32460
32533
|
figureUI: Object,
|
|
32461
|
-
onFigureDeleted: Function,
|
|
32462
32534
|
editFigureStyle: { type: Function, optional: true },
|
|
32463
32535
|
isFullScreen: { type: Boolean, optional: true },
|
|
32464
32536
|
openContextMenu: { type: Function, optional: true },
|
|
@@ -32607,7 +32679,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32607
32679
|
static template = "o-spreadsheet-ChartFigure";
|
|
32608
32680
|
static props = {
|
|
32609
32681
|
figureUI: Object,
|
|
32610
|
-
onFigureDeleted: Function,
|
|
32611
32682
|
editFigureStyle: { type: Function, optional: true },
|
|
32612
32683
|
isFullScreen: { type: Boolean, optional: true },
|
|
32613
32684
|
openContextMenu: { type: Function, optional: true },
|
|
@@ -32641,7 +32712,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32641
32712
|
static template = "o-spreadsheet-ImageFigure";
|
|
32642
32713
|
static props = {
|
|
32643
32714
|
figureUI: Object,
|
|
32644
|
-
onFigureDeleted: Function,
|
|
32645
32715
|
editFigureStyle: { type: Function, optional: true },
|
|
32646
32716
|
openContextMenu: { type: Function, optional: true },
|
|
32647
32717
|
};
|
|
@@ -32760,13 +32830,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32760
32830
|
figureUI: Object,
|
|
32761
32831
|
style: { type: String, optional: true },
|
|
32762
32832
|
class: { type: String, optional: true },
|
|
32763
|
-
onFigureDeleted: { type: Function, optional: true },
|
|
32764
32833
|
onMouseDown: { type: Function, optional: true },
|
|
32765
32834
|
onClickAnchor: { type: Function, optional: true },
|
|
32766
32835
|
};
|
|
32767
32836
|
static components = { MenuPopover };
|
|
32768
32837
|
static defaultProps = {
|
|
32769
|
-
onFigureDeleted: () => { },
|
|
32770
32838
|
onMouseDown: () => { },
|
|
32771
32839
|
onClickAnchor: () => { },
|
|
32772
32840
|
};
|
|
@@ -32844,9 +32912,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32844
32912
|
this.props.figureUI.id,
|
|
32845
32913
|
this.figureRef.el,
|
|
32846
32914
|
]);
|
|
32847
|
-
owl.onWillUnmount(() => {
|
|
32848
|
-
this.props.onFigureDeleted();
|
|
32849
|
-
});
|
|
32850
32915
|
}
|
|
32851
32916
|
clickAnchor(dirX, dirY, ev) {
|
|
32852
32917
|
this.props.onClickAnchor(dirX, dirY, ev);
|
|
@@ -32870,7 +32935,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32870
32935
|
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
32871
32936
|
figureId: this.props.figureUI.id,
|
|
32872
32937
|
});
|
|
32873
|
-
this.props.onFigureDeleted();
|
|
32874
32938
|
ev.preventDefault();
|
|
32875
32939
|
ev.stopPropagation();
|
|
32876
32940
|
break;
|
|
@@ -32963,7 +33027,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32963
33027
|
this.menuState.anchorRect = anchorRect;
|
|
32964
33028
|
this.menuState.menuItems = figureRegistry
|
|
32965
33029
|
.get(this.props.figureUI.tag)
|
|
32966
|
-
.menuBuilder(this.props.figureUI.id, this.
|
|
33030
|
+
.menuBuilder(this.props.figureUI.id, this.env);
|
|
32967
33031
|
}
|
|
32968
33032
|
editWrapperStyle(properties) {
|
|
32969
33033
|
if (this.figureWrapperRef.el) {
|
|
@@ -33335,7 +33399,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
33335
33399
|
return false;
|
|
33336
33400
|
}
|
|
33337
33401
|
if (["lastWeek", "lastMonth", "lastYear"].includes(criterion.dateValue)) {
|
|
33338
|
-
const today =
|
|
33402
|
+
const today = Math.floor(jsDateToNumber(DateTime.now()));
|
|
33339
33403
|
return isDateBetween(dateValue, today, criterionValue);
|
|
33340
33404
|
}
|
|
33341
33405
|
return areDatesSameDay(dateValue, criterionValue);
|
|
@@ -34404,7 +34468,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34404
34468
|
assistantStyle["max-height"] = `${availableSpaceAbove - CLOSE_ICON_RADIUS}px`;
|
|
34405
34469
|
// render top
|
|
34406
34470
|
// We compensate 2 px of margin on the assistant style + 1px for design reasons
|
|
34407
|
-
assistantStyle.
|
|
34471
|
+
assistantStyle.top = `-3px`;
|
|
34472
|
+
assistantStyle.transform = `translate(0, -100%)`;
|
|
34408
34473
|
}
|
|
34409
34474
|
if (cellX + ASSISTANT_WIDTH > this.props.delimitation.width) {
|
|
34410
34475
|
// render left
|
|
@@ -35195,7 +35260,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35195
35260
|
}
|
|
35196
35261
|
this.selectionStart = start;
|
|
35197
35262
|
this.selectionEnd = end;
|
|
35198
|
-
this.
|
|
35263
|
+
this.stopComposerRangeSelection();
|
|
35199
35264
|
this.computeFormulaCursorContext();
|
|
35200
35265
|
this.computeParenthesisRelatedToCursor();
|
|
35201
35266
|
this.updateAutoCompleteProvider();
|
|
@@ -37448,6 +37513,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
37448
37513
|
}
|
|
37449
37514
|
setup() {
|
|
37450
37515
|
owl.useEffect(() => this.focusedInput.el?.focus(), () => [this.focusedInput.el]);
|
|
37516
|
+
owl.useEffect(() => {
|
|
37517
|
+
// Check the offsetParent to know if the input or an ancestor is `display: none` (eg. when changing side panel tab)
|
|
37518
|
+
if (this.store.hasFocus && this.selectionRef.el?.offsetParent === null) {
|
|
37519
|
+
this.reset();
|
|
37520
|
+
}
|
|
37521
|
+
});
|
|
37451
37522
|
this.store = useLocalStore(SelectionInputStore, this.props.ranges, this.props.hasSingleRange || false, this.props.colors, this.props.disabledRanges);
|
|
37452
37523
|
owl.onWillUpdateProps((nextProps) => {
|
|
37453
37524
|
if (nextProps.ranges.join() !== this.store.selectionInputValues.join()) {
|
|
@@ -44192,18 +44263,22 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
44192
44263
|
return messages;
|
|
44193
44264
|
}
|
|
44194
44265
|
function fixChartDefinitions(data, initialMessages) {
|
|
44266
|
+
/**
|
|
44267
|
+
* Revisions created after version 18.5.1 contain the full chart definition in the command
|
|
44268
|
+
* if the data was alreay updated to 18.5.1, then those older revision cannot (by definition) be reaplied
|
|
44269
|
+
* and should not be replayed.
|
|
44270
|
+
* FIXME: every command should be versionned when upgraded to allow finer tuning.
|
|
44271
|
+
*/
|
|
44272
|
+
if (!data.version || compareVersions(String(data.version), "18.5.1") >= 0) {
|
|
44273
|
+
return initialMessages;
|
|
44274
|
+
}
|
|
44195
44275
|
const messages = [];
|
|
44196
44276
|
const map = {};
|
|
44197
44277
|
for (const sheet of data.sheets || []) {
|
|
44198
44278
|
sheet.figures?.forEach((figure) => {
|
|
44199
44279
|
if (figure.tag === "chart") {
|
|
44200
44280
|
// chart definition
|
|
44201
|
-
|
|
44202
|
-
map[figure.data.chartId] = figure.data;
|
|
44203
|
-
}
|
|
44204
|
-
else {
|
|
44205
|
-
map[figure.id] = figure.data;
|
|
44206
|
-
}
|
|
44281
|
+
map[figure.id] = figure.data;
|
|
44207
44282
|
}
|
|
44208
44283
|
});
|
|
44209
44284
|
}
|
|
@@ -45227,7 +45302,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
45227
45302
|
const leftOffset = isLeftUnbounded || left?.colFixed ? 0 : colCellOffset;
|
|
45228
45303
|
const topOffset = isTopUnbounded || left?.rowFixed ? 0 : rowCellOffset;
|
|
45229
45304
|
const isRightFixed = (!right && left?.colFixed) || right?.colFixed;
|
|
45230
|
-
const isBottomFixed = (!right && left
|
|
45305
|
+
const isBottomFixed = (!right && left?.rowFixed) || right?.rowFixed;
|
|
45231
45306
|
const isRightUnbounded = range.unboundedZone.right === undefined;
|
|
45232
45307
|
const isBottomUnbounded = range.unboundedZone.bottom === undefined;
|
|
45233
45308
|
const rightOffset = isRightUnbounded || isRightFixed ? 0 : colCellOffset;
|
|
@@ -47786,13 +47861,42 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
47786
47861
|
pivotRegistry.add("SPREADSHEET", {
|
|
47787
47862
|
ui: SpreadsheetPivot,
|
|
47788
47863
|
definition: SpreadsheetPivotRuntimeDefinition,
|
|
47789
|
-
externalData: false,
|
|
47790
47864
|
dateGranularities: [...dateGranularities],
|
|
47791
47865
|
datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
|
|
47792
47866
|
isMeasureCandidate: (field) => field.type !== "boolean",
|
|
47793
47867
|
isGroupable: () => true,
|
|
47794
47868
|
canHaveCustomGroup: (field) => field.type === "char" && !field.isCustomField,
|
|
47869
|
+
adaptRanges: (getters, definition, applyChange) => {
|
|
47870
|
+
if (definition.type !== "SPREADSHEET" || !definition.dataSet) {
|
|
47871
|
+
return definition;
|
|
47872
|
+
}
|
|
47873
|
+
const { sheetId, zone } = definition.dataSet;
|
|
47874
|
+
const range = getters.getRangeFromZone(sheetId, zone);
|
|
47875
|
+
const adaptedRange = adaptPivotRange(range, applyChange);
|
|
47876
|
+
if (adaptedRange === range) {
|
|
47877
|
+
return definition;
|
|
47878
|
+
}
|
|
47879
|
+
const dataSet = adaptedRange && {
|
|
47880
|
+
sheetId: adaptedRange.sheetId,
|
|
47881
|
+
zone: adaptedRange.zone,
|
|
47882
|
+
};
|
|
47883
|
+
return { ...definition, dataSet };
|
|
47884
|
+
},
|
|
47795
47885
|
});
|
|
47886
|
+
function adaptPivotRange(range, applyChange) {
|
|
47887
|
+
if (!range) {
|
|
47888
|
+
return undefined;
|
|
47889
|
+
}
|
|
47890
|
+
const change = applyChange(range);
|
|
47891
|
+
switch (change.changeType) {
|
|
47892
|
+
case "NONE":
|
|
47893
|
+
return range;
|
|
47894
|
+
case "REMOVE":
|
|
47895
|
+
return undefined;
|
|
47896
|
+
default:
|
|
47897
|
+
return change.range;
|
|
47898
|
+
}
|
|
47899
|
+
}
|
|
47796
47900
|
|
|
47797
47901
|
const pivotProperties = {
|
|
47798
47902
|
name: _t("See pivot properties"),
|
|
@@ -49063,7 +49167,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
49063
49167
|
}
|
|
49064
49168
|
get highlights() {
|
|
49065
49169
|
const position = this.model.getters.getActivePosition();
|
|
49066
|
-
const cell = this.getters.getEvaluatedCell(position);
|
|
49067
49170
|
const spreader = this.model.getters.getArrayFormulaSpreadingOn(position);
|
|
49068
49171
|
const zone = spreader
|
|
49069
49172
|
? this.model.getters.getSpreadZone(spreader, { ignoreSpillError: true })
|
|
@@ -49071,10 +49174,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
49071
49174
|
if (!zone) {
|
|
49072
49175
|
return [];
|
|
49073
49176
|
}
|
|
49177
|
+
const isArrayFormulaBlocked = this.model.getters.isArrayFormulaSpillBlocked(spreader ?? position);
|
|
49074
49178
|
return [
|
|
49075
49179
|
{
|
|
49076
49180
|
range: this.model.getters.getRangeFromZone(position.sheetId, zone),
|
|
49077
|
-
dashed:
|
|
49181
|
+
dashed: isArrayFormulaBlocked,
|
|
49078
49182
|
color: "#17A2B8",
|
|
49079
49183
|
noFill: true,
|
|
49080
49184
|
thinLine: true,
|
|
@@ -50481,9 +50585,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
50481
50585
|
*/
|
|
50482
50586
|
class FiguresContainer extends owl.Component {
|
|
50483
50587
|
static template = "o-spreadsheet-FiguresContainer";
|
|
50484
|
-
static props = {
|
|
50485
|
-
onFigureDeleted: Function,
|
|
50486
|
-
};
|
|
50588
|
+
static props = {};
|
|
50487
50589
|
static components = { FigureComponent };
|
|
50488
50590
|
dnd = owl.useState({
|
|
50489
50591
|
draggedFigure: undefined,
|
|
@@ -50693,7 +50795,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
50693
50795
|
carouselFigureId: this.dnd.overlappingCarousel.id,
|
|
50694
50796
|
chartFigureId: figureUI.id,
|
|
50695
50797
|
});
|
|
50696
|
-
this.props.onFigureDeleted();
|
|
50697
50798
|
}
|
|
50698
50799
|
this.dnd.draggedFigure = undefined;
|
|
50699
50800
|
this.dnd.horizontalSnap = undefined;
|
|
@@ -50919,16 +51020,16 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
50919
51020
|
`;
|
|
50920
51021
|
class GridAddRowsFooter extends owl.Component {
|
|
50921
51022
|
static template = "o-spreadsheet-GridAddRowsFooter";
|
|
50922
|
-
static props = {
|
|
50923
|
-
focusGrid: Function,
|
|
50924
|
-
};
|
|
51023
|
+
static props = {};
|
|
50925
51024
|
static components = { ValidationMessages };
|
|
51025
|
+
DOMFocusableElementStore;
|
|
50926
51026
|
inputRef = owl.useRef("inputRef");
|
|
50927
51027
|
state = owl.useState({
|
|
50928
51028
|
inputValue: "100",
|
|
50929
51029
|
errorFlag: false,
|
|
50930
51030
|
});
|
|
50931
51031
|
setup() {
|
|
51032
|
+
this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
|
|
50932
51033
|
owl.useExternalListener(window, "click", this.onExternalClick, { capture: true });
|
|
50933
51034
|
}
|
|
50934
51035
|
get addRowsPosition() {
|
|
@@ -50946,7 +51047,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
50946
51047
|
}
|
|
50947
51048
|
onKeydown(ev) {
|
|
50948
51049
|
if (ev.key.toUpperCase() === "ESCAPE") {
|
|
50949
|
-
this.
|
|
51050
|
+
this.focusDefaultElement();
|
|
50950
51051
|
}
|
|
50951
51052
|
else if (ev.key.toUpperCase() === "ENTER") {
|
|
50952
51053
|
this.onConfirm();
|
|
@@ -50973,7 +51074,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
50973
51074
|
quantity,
|
|
50974
51075
|
dimension: "ROW",
|
|
50975
51076
|
});
|
|
50976
|
-
this.
|
|
51077
|
+
this.focusDefaultElement();
|
|
50977
51078
|
// After adding new rows, scroll down to the new last row
|
|
50978
51079
|
const { scrollX } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
50979
51080
|
const { end } = this.env.model.getters.getRowDimensions(activeSheetId, rowNumber + quantity - 1);
|
|
@@ -50986,7 +51087,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
50986
51087
|
if (this.inputRef.el !== document.activeElement || ev.target === this.inputRef.el) {
|
|
50987
51088
|
return;
|
|
50988
51089
|
}
|
|
50989
|
-
this.
|
|
51090
|
+
this.focusDefaultElement();
|
|
51091
|
+
}
|
|
51092
|
+
focusDefaultElement() {
|
|
51093
|
+
if (document.activeElement === this.inputRef.el) {
|
|
51094
|
+
this.DOMFocusableElementStore.focus();
|
|
51095
|
+
}
|
|
50990
51096
|
}
|
|
50991
51097
|
}
|
|
50992
51098
|
|
|
@@ -51261,7 +51367,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51261
51367
|
onCellClicked: { type: Function, optional: true },
|
|
51262
51368
|
onCellRightClicked: { type: Function, optional: true },
|
|
51263
51369
|
onGridResized: { type: Function, optional: true },
|
|
51264
|
-
onFigureDeleted: { type: Function, optional: true },
|
|
51265
51370
|
onGridMoved: Function,
|
|
51266
51371
|
gridOverlayDimensions: String,
|
|
51267
51372
|
slots: { type: Object, optional: true },
|
|
@@ -51276,7 +51381,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51276
51381
|
onCellClicked: () => { },
|
|
51277
51382
|
onCellRightClicked: () => { },
|
|
51278
51383
|
onGridResized: () => { },
|
|
51279
|
-
onFigureDeleted: () => { },
|
|
51280
51384
|
};
|
|
51281
51385
|
gridOverlay = owl.useRef("gridOverlay");
|
|
51282
51386
|
cellPopovers;
|
|
@@ -53822,7 +53926,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
53822
53926
|
inputRef = owl.useRef("inputFontSize");
|
|
53823
53927
|
rootEditorRef = owl.useRef("FontSizeEditor");
|
|
53824
53928
|
fontSizeListRef = owl.useRef("fontSizeList");
|
|
53929
|
+
DOMFocusableElementStore;
|
|
53825
53930
|
setup() {
|
|
53931
|
+
this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
|
|
53826
53932
|
owl.useExternalListener(window, "click", this.onExternalClick, { capture: true });
|
|
53827
53933
|
}
|
|
53828
53934
|
get popoverProps() {
|
|
@@ -53876,6 +53982,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
53876
53982
|
}
|
|
53877
53983
|
this.props.onToggle?.();
|
|
53878
53984
|
}
|
|
53985
|
+
if (ev.key === "Tab") {
|
|
53986
|
+
ev.preventDefault();
|
|
53987
|
+
ev.stopPropagation();
|
|
53988
|
+
this.closeFontList();
|
|
53989
|
+
this.DOMFocusableElementStore.focus();
|
|
53990
|
+
return;
|
|
53991
|
+
}
|
|
53879
53992
|
}
|
|
53880
53993
|
}
|
|
53881
53994
|
|
|
@@ -55211,19 +55324,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
55211
55324
|
}
|
|
55212
55325
|
}
|
|
55213
55326
|
|
|
55214
|
-
class ChartShowDataMarkers extends owl.Component {
|
|
55215
|
-
static template = "o-spreadsheet-ChartShowDataMarkers";
|
|
55216
|
-
static components = {
|
|
55217
|
-
Checkbox,
|
|
55218
|
-
};
|
|
55219
|
-
static props = {
|
|
55220
|
-
chartId: String,
|
|
55221
|
-
definition: Object,
|
|
55222
|
-
updateChart: Function,
|
|
55223
|
-
canUpdateChart: Function,
|
|
55224
|
-
};
|
|
55225
|
-
}
|
|
55226
|
-
|
|
55227
55327
|
class GenericZoomableChartDesignPanel extends ChartWithAxisDesignPanel {
|
|
55228
55328
|
static template = "o-spreadsheet-GenericZoomableChartDesignPanel";
|
|
55229
55329
|
static components = {
|
|
@@ -55237,6 +55337,26 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
55237
55337
|
}
|
|
55238
55338
|
}
|
|
55239
55339
|
|
|
55340
|
+
class BarChartDesignPanel extends GenericZoomableChartDesignPanel {
|
|
55341
|
+
static template = "o-spreadsheet-BarChartDesignPanel";
|
|
55342
|
+
get isZoomable() {
|
|
55343
|
+
return !this.props.definition.horizontal;
|
|
55344
|
+
}
|
|
55345
|
+
}
|
|
55346
|
+
|
|
55347
|
+
class ChartShowDataMarkers extends owl.Component {
|
|
55348
|
+
static template = "o-spreadsheet-ChartShowDataMarkers";
|
|
55349
|
+
static components = {
|
|
55350
|
+
Checkbox,
|
|
55351
|
+
};
|
|
55352
|
+
static props = {
|
|
55353
|
+
chartId: String,
|
|
55354
|
+
definition: Object,
|
|
55355
|
+
updateChart: Function,
|
|
55356
|
+
canUpdateChart: Function,
|
|
55357
|
+
};
|
|
55358
|
+
}
|
|
55359
|
+
|
|
55240
55360
|
class ComboChartDesignPanel extends GenericZoomableChartDesignPanel {
|
|
55241
55361
|
static template = "o-spreadsheet-ComboChartDesignPanel";
|
|
55242
55362
|
static components = {
|
|
@@ -56165,7 +56285,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
56165
56285
|
})
|
|
56166
56286
|
.add("bar", {
|
|
56167
56287
|
configuration: BarConfigPanel,
|
|
56168
|
-
design:
|
|
56288
|
+
design: BarChartDesignPanel,
|
|
56169
56289
|
})
|
|
56170
56290
|
.add("combo", {
|
|
56171
56291
|
configuration: GenericChartConfigPanel,
|
|
@@ -56526,7 +56646,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
56526
56646
|
}
|
|
56527
56647
|
|
|
56528
56648
|
css /* scss */ `
|
|
56529
|
-
.o-cf-preview {
|
|
56649
|
+
.o-spreadsheet .o-cf-preview {
|
|
56530
56650
|
&.o-cf-cursor-ptr {
|
|
56531
56651
|
cursor: pointer;
|
|
56532
56652
|
}
|
|
@@ -56534,6 +56654,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
56534
56654
|
border-bottom: 1px solid ${GRAY_300};
|
|
56535
56655
|
height: 80px;
|
|
56536
56656
|
padding: 10px;
|
|
56657
|
+
box-sizing: border-box;
|
|
56537
56658
|
position: relative;
|
|
56538
56659
|
cursor: pointer;
|
|
56539
56660
|
&:hover,
|
|
@@ -56547,7 +56668,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
56547
56668
|
.o-cf-preview-icon {
|
|
56548
56669
|
border: 1px solid ${GRAY_300};
|
|
56549
56670
|
background-color: #fff;
|
|
56550
|
-
position: absolute;
|
|
56551
56671
|
height: 50px;
|
|
56552
56672
|
width: 50px;
|
|
56553
56673
|
.o-icon {
|
|
@@ -56556,12 +56676,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
56556
56676
|
}
|
|
56557
56677
|
}
|
|
56558
56678
|
.o-cf-preview-description {
|
|
56559
|
-
left: 65px;
|
|
56560
|
-
margin-bottom: auto;
|
|
56561
|
-
margin-right: 8px;
|
|
56562
|
-
margin-top: auto;
|
|
56563
|
-
position: relative;
|
|
56564
|
-
width: 142px;
|
|
56565
56679
|
.o-cf-preview-description-rule {
|
|
56566
56680
|
margin-bottom: 4px;
|
|
56567
56681
|
max-height: 2.8em;
|
|
@@ -56571,16 +56685,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
56571
56685
|
font-size: 12px;
|
|
56572
56686
|
}
|
|
56573
56687
|
}
|
|
56574
|
-
.o-cf-delete {
|
|
56575
|
-
left: 90%;
|
|
56576
|
-
top: 39%;
|
|
56577
|
-
position: absolute;
|
|
56578
|
-
}
|
|
56579
56688
|
&:not(:hover):not(.o-cf-dragging) .o-cf-drag-handle {
|
|
56580
56689
|
display: none !important;
|
|
56581
56690
|
}
|
|
56582
56691
|
.o-cf-drag-handle {
|
|
56583
|
-
left:
|
|
56692
|
+
left: 2px;
|
|
56584
56693
|
cursor: move;
|
|
56585
56694
|
.o-icon {
|
|
56586
56695
|
width: 6px;
|
|
@@ -62385,10 +62494,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
62385
62494
|
// existingBorderSideToClear[side] = true means we should clear the border on that
|
|
62386
62495
|
// side of the existing adjacent zone before adding the new border.
|
|
62387
62496
|
const existingBorderSideToClear = {
|
|
62388
|
-
left:
|
|
62389
|
-
right:
|
|
62390
|
-
top:
|
|
62391
|
-
bottom:
|
|
62497
|
+
left: !!newBorder?.right,
|
|
62498
|
+
right: !!newBorder?.left,
|
|
62499
|
+
top: !!newBorder?.bottom,
|
|
62500
|
+
bottom: !!newBorder?.top,
|
|
62392
62501
|
};
|
|
62393
62502
|
let editingZone = [zone];
|
|
62394
62503
|
for (const existingBorder of this.borders[sheetId] ?? []) {
|
|
@@ -64257,7 +64366,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
64257
64366
|
}
|
|
64258
64367
|
break;
|
|
64259
64368
|
case "DUPLICATE_SHEET": {
|
|
64260
|
-
for (const
|
|
64369
|
+
for (const figure of this.getFigures(cmd.sheetId)) {
|
|
64370
|
+
const figureId = figure.id;
|
|
64261
64371
|
const fig = this.figures[cmd.sheetId]?.[figureId];
|
|
64262
64372
|
if (!fig) {
|
|
64263
64373
|
continue;
|
|
@@ -65380,6 +65490,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
65380
65490
|
class RangeAdapter {
|
|
65381
65491
|
getters;
|
|
65382
65492
|
providers = [];
|
|
65493
|
+
isAdaptingRanges = false;
|
|
65383
65494
|
constructor(getters) {
|
|
65384
65495
|
this.getters = getters;
|
|
65385
65496
|
}
|
|
@@ -65411,6 +65522,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
65411
65522
|
}
|
|
65412
65523
|
beforeHandle(command) { }
|
|
65413
65524
|
handle(cmd) {
|
|
65525
|
+
if (this.isAdaptingRanges) {
|
|
65526
|
+
throw new Error("Plugins cannot dispatch commands during adaptRanges phase");
|
|
65527
|
+
}
|
|
65414
65528
|
const rangeAdapter = getRangeAdapter(cmd);
|
|
65415
65529
|
if (rangeAdapter?.applyChange) {
|
|
65416
65530
|
this.executeOnAllRanges(rangeAdapter.applyChange, rangeAdapter.sheetId, rangeAdapter.sheetName);
|
|
@@ -65433,10 +65547,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
65433
65547
|
};
|
|
65434
65548
|
}
|
|
65435
65549
|
executeOnAllRanges(adaptRange, sheetId, sheetName) {
|
|
65550
|
+
this.isAdaptingRanges = true;
|
|
65436
65551
|
const func = this.verifyRangeRemoved(adaptRange);
|
|
65437
65552
|
for (const provider of this.providers) {
|
|
65438
65553
|
provider(func, sheetId, sheetName);
|
|
65439
65554
|
}
|
|
65555
|
+
this.isAdaptingRanges = false;
|
|
65440
65556
|
}
|
|
65441
65557
|
/**
|
|
65442
65558
|
* Stores the functions bound to each plugin to be able to iterate over all ranges of the application,
|
|
@@ -65753,7 +65869,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
65753
65869
|
break;
|
|
65754
65870
|
case "CREATE_SHEET":
|
|
65755
65871
|
const sheet = this.createSheet(cmd.sheetId, cmd.name || this.getNextSheetName(), cmd.cols || 26, cmd.rows || 100, cmd.position);
|
|
65756
|
-
this.history.update("sheetIdsMapName", sheet.name, sheet.id);
|
|
65872
|
+
this.history.update("sheetIdsMapName", toStandardizedSheetName(sheet.name), sheet.id);
|
|
65757
65873
|
break;
|
|
65758
65874
|
case "MOVE_SHEET":
|
|
65759
65875
|
this.moveSheet(cmd.sheetId, cmd.delta);
|
|
@@ -65820,7 +65936,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
65820
65936
|
// that depends on a sheet not already imported will not be able to be
|
|
65821
65937
|
// compiled
|
|
65822
65938
|
for (const sheet of data.sheets) {
|
|
65823
|
-
this.sheetIdsMapName[sheet.name] = sheet.id;
|
|
65939
|
+
this.sheetIdsMapName[toStandardizedSheetName(sheet.name)] = sheet.id;
|
|
65824
65940
|
}
|
|
65825
65941
|
for (const sheetData of data.sheets) {
|
|
65826
65942
|
const name = sheetData.name || "Sheet" + (Object.keys(this.sheets).length + 1);
|
|
@@ -65910,12 +66026,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
65910
66026
|
}
|
|
65911
66027
|
getSheetIdByName(name) {
|
|
65912
66028
|
if (name) {
|
|
65913
|
-
|
|
65914
|
-
for (const key in this.sheetIdsMapName) {
|
|
65915
|
-
if (isSheetNameEqual(key, unquotedName)) {
|
|
65916
|
-
return this.sheetIdsMapName[key];
|
|
65917
|
-
}
|
|
65918
|
-
}
|
|
66029
|
+
return this.sheetIdsMapName[toStandardizedSheetName(name)];
|
|
65919
66030
|
}
|
|
65920
66031
|
return undefined;
|
|
65921
66032
|
}
|
|
@@ -66215,8 +66326,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
66215
66326
|
const oldName = sheet.name;
|
|
66216
66327
|
this.history.update("sheets", sheet.id, "name", name.trim());
|
|
66217
66328
|
const sheetIdsMapName = Object.assign({}, this.sheetIdsMapName);
|
|
66218
|
-
delete sheetIdsMapName[oldName];
|
|
66219
|
-
sheetIdsMapName[name] = sheet.id;
|
|
66329
|
+
delete sheetIdsMapName[toStandardizedSheetName(oldName)];
|
|
66330
|
+
sheetIdsMapName[toStandardizedSheetName(name)] = sheet.id;
|
|
66220
66331
|
this.history.update("sheetIdsMapName", sheetIdsMapName);
|
|
66221
66332
|
}
|
|
66222
66333
|
hideSheet(sheetId) {
|
|
@@ -66254,7 +66365,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
66254
66365
|
});
|
|
66255
66366
|
}
|
|
66256
66367
|
const sheetIdsMapName = Object.assign({}, this.sheetIdsMapName);
|
|
66257
|
-
sheetIdsMapName[newSheet.name] = newSheet.id;
|
|
66368
|
+
sheetIdsMapName[toStandardizedSheetName(newSheet.name)] = newSheet.id;
|
|
66258
66369
|
this.history.update("sheetIdsMapName", sheetIdsMapName);
|
|
66259
66370
|
}
|
|
66260
66371
|
getDuplicateSheetName(sheetName) {
|
|
@@ -66271,7 +66382,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
66271
66382
|
orderedSheetIds.splice(currentIndex, 1);
|
|
66272
66383
|
this.history.update("orderedSheetIds", orderedSheetIds);
|
|
66273
66384
|
const sheetIdsMapName = Object.assign({}, this.sheetIdsMapName);
|
|
66274
|
-
delete sheetIdsMapName[name];
|
|
66385
|
+
delete sheetIdsMapName[toStandardizedSheetName(name)];
|
|
66275
66386
|
this.history.update("sheetIdsMapName", sheetIdsMapName);
|
|
66276
66387
|
}
|
|
66277
66388
|
/**
|
|
@@ -67591,6 +67702,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67591
67702
|
}
|
|
67592
67703
|
}
|
|
67593
67704
|
adaptRanges(applyChange) {
|
|
67705
|
+
for (const pivotId in this.pivots) {
|
|
67706
|
+
const definition = deepCopy(this.pivots[pivotId]?.definition);
|
|
67707
|
+
if (!definition) {
|
|
67708
|
+
continue;
|
|
67709
|
+
}
|
|
67710
|
+
const newDefinition = pivotRegistry
|
|
67711
|
+
.get(definition.type)
|
|
67712
|
+
?.adaptRanges?.(this.getters, definition, applyChange);
|
|
67713
|
+
if (newDefinition && !deepEquals(definition, newDefinition)) {
|
|
67714
|
+
this.history.update("pivots", pivotId, "definition", newDefinition);
|
|
67715
|
+
}
|
|
67716
|
+
}
|
|
67594
67717
|
for (const sheetId in this.compiledMeasureFormulas) {
|
|
67595
67718
|
for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
|
|
67596
67719
|
const compiledFormula = this.compiledMeasureFormulas[sheetId][formulaString];
|
|
@@ -67865,20 +67988,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67865
67988
|
}
|
|
67866
67989
|
}
|
|
67867
67990
|
|
|
67868
|
-
function adaptPivotRange(range, applyChange) {
|
|
67869
|
-
if (!range) {
|
|
67870
|
-
return undefined;
|
|
67871
|
-
}
|
|
67872
|
-
const change = applyChange(range);
|
|
67873
|
-
switch (change.changeType) {
|
|
67874
|
-
case "NONE":
|
|
67875
|
-
return range;
|
|
67876
|
-
case "REMOVE":
|
|
67877
|
-
return undefined;
|
|
67878
|
-
default:
|
|
67879
|
-
return change.range;
|
|
67880
|
-
}
|
|
67881
|
-
}
|
|
67882
67991
|
class SpreadsheetPivotCorePlugin extends CorePlugin {
|
|
67883
67992
|
allowDispatch(cmd) {
|
|
67884
67993
|
switch (cmd.type) {
|
|
@@ -67889,24 +67998,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67889
67998
|
}
|
|
67890
67999
|
return "Success" /* CommandResult.Success */;
|
|
67891
68000
|
}
|
|
67892
|
-
adaptRanges(applyChange) {
|
|
67893
|
-
for (const pivotId of this.getters.getPivotIds()) {
|
|
67894
|
-
const definition = this.getters.getPivotCoreDefinition(pivotId);
|
|
67895
|
-
if (definition.type !== "SPREADSHEET") {
|
|
67896
|
-
continue;
|
|
67897
|
-
}
|
|
67898
|
-
if (definition.dataSet) {
|
|
67899
|
-
const { sheetId, zone } = definition.dataSet;
|
|
67900
|
-
const range = this.getters.getRangeFromZone(sheetId, zone);
|
|
67901
|
-
const adaptedRange = adaptPivotRange(range, applyChange);
|
|
67902
|
-
const dataSet = adaptedRange && {
|
|
67903
|
-
sheetId: adaptedRange.sheetId,
|
|
67904
|
-
zone: adaptedRange.zone,
|
|
67905
|
-
};
|
|
67906
|
-
this.dispatch("UPDATE_PIVOT", { pivotId, pivot: { ...definition, dataSet } });
|
|
67907
|
-
}
|
|
67908
|
-
}
|
|
67909
|
-
}
|
|
67910
68001
|
checkDataSetValidity(definition) {
|
|
67911
68002
|
if (definition.type === "SPREADSHEET" && definition.dataSet) {
|
|
67912
68003
|
const { zone, sheetId } = definition.dataSet;
|
|
@@ -68905,13 +68996,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68905
68996
|
}
|
|
68906
68997
|
return result;
|
|
68907
68998
|
}
|
|
68908
|
-
size() {
|
|
68909
|
-
let size = 0;
|
|
68910
|
-
for (const profile of this.profiles.values()) {
|
|
68911
|
-
size += profile.length;
|
|
68912
|
-
}
|
|
68913
|
-
return size / 2;
|
|
68914
|
-
}
|
|
68915
68999
|
/**
|
|
68916
69000
|
* iterator of all the zones in the ZoneSet
|
|
68917
69001
|
*/
|
|
@@ -68993,13 +69077,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68993
69077
|
clear() {
|
|
68994
69078
|
this.setsBySheetId = {};
|
|
68995
69079
|
}
|
|
68996
|
-
size() {
|
|
68997
|
-
let size = 0;
|
|
68998
|
-
for (const sheetId in this.setsBySheetId) {
|
|
68999
|
-
size += this.setsBySheetId[sheetId].size();
|
|
69000
|
-
}
|
|
69001
|
-
return size;
|
|
69002
|
-
}
|
|
69003
69080
|
isEmpty() {
|
|
69004
69081
|
for (const sheetId in this.setsBySheetId) {
|
|
69005
69082
|
if (!this.setsBySheetId[sheetId].isEmpty()) {
|
|
@@ -69503,6 +69580,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
69503
69580
|
const arrayFormulas = this.spreadingRelations.searchFormulaPositionsSpreadingOn(position.sheetId, positionToZone(position));
|
|
69504
69581
|
return arrayFormulas.find((position) => !this.blockedArrayFormulas.has(position));
|
|
69505
69582
|
}
|
|
69583
|
+
isArrayFormulaSpillBlocked(position) {
|
|
69584
|
+
return this.blockedArrayFormulas.has(position);
|
|
69585
|
+
}
|
|
69506
69586
|
updateDependencies(position) {
|
|
69507
69587
|
// removing dependencies is slow because it requires
|
|
69508
69588
|
// to traverse the entire r-tree.
|
|
@@ -69514,13 +69594,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
69514
69594
|
addDependencies(position, dependencies) {
|
|
69515
69595
|
this.formulaDependencies().addDependencies(position, dependencies);
|
|
69516
69596
|
for (const range of dependencies) {
|
|
69517
|
-
|
|
69518
|
-
|
|
69519
|
-
for (let col = left; col <= right; col++) {
|
|
69520
|
-
for (let row = top; row <= bottom; row++) {
|
|
69521
|
-
this.computeAndSave({ sheetId, col, row });
|
|
69522
|
-
}
|
|
69523
|
-
}
|
|
69597
|
+
// ensure that all ranges are computed
|
|
69598
|
+
this.compilationParams.ensureRange(range, false);
|
|
69524
69599
|
}
|
|
69525
69600
|
}
|
|
69526
69601
|
updateCompilationParameters() {
|
|
@@ -69748,6 +69823,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
69748
69823
|
this.assertSheetHasEnoughSpaceToSpreadFormulaResult(formulaPosition, formulaReturn);
|
|
69749
69824
|
const nbColumns = formulaReturn.length;
|
|
69750
69825
|
const nbRows = formulaReturn[0].length;
|
|
69826
|
+
if (nbRows === 0) {
|
|
69827
|
+
// empty matrix
|
|
69828
|
+
return createEvaluatedCell({ value: 0 }, this.getters.getLocale(), cellData);
|
|
69829
|
+
}
|
|
69751
69830
|
const resultZone = {
|
|
69752
69831
|
top: formulaPosition.row,
|
|
69753
69832
|
bottom: formulaPosition.row + nbRows - 1,
|
|
@@ -70018,6 +70097,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
70018
70097
|
"getEvaluatedCellsPositions",
|
|
70019
70098
|
"getSpreadZone",
|
|
70020
70099
|
"getArrayFormulaSpreadingOn",
|
|
70100
|
+
"isArrayFormulaSpillBlocked",
|
|
70021
70101
|
"isEmpty",
|
|
70022
70102
|
];
|
|
70023
70103
|
shouldRebuildDependenciesGraph = true;
|
|
@@ -70137,6 +70217,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
70137
70217
|
getArrayFormulaSpreadingOn(position) {
|
|
70138
70218
|
return this.evaluator.getArrayFormulaSpreadingOn(position);
|
|
70139
70219
|
}
|
|
70220
|
+
isArrayFormulaSpillBlocked(position) {
|
|
70221
|
+
return this.evaluator.isArrayFormulaSpillBlocked(position);
|
|
70222
|
+
}
|
|
70140
70223
|
/**
|
|
70141
70224
|
* Check if a zone only contains empty cells
|
|
70142
70225
|
*/
|
|
@@ -72218,9 +72301,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
72218
72301
|
handle(cmd) {
|
|
72219
72302
|
if (invalidateEvaluationCommands.has(cmd.type)) {
|
|
72220
72303
|
for (const pivotId of this.getters.getPivotIds()) {
|
|
72221
|
-
|
|
72222
|
-
this.setupPivot(pivotId, { recreate: true });
|
|
72223
|
-
}
|
|
72304
|
+
this.setupPivot(pivotId, { recreate: true });
|
|
72224
72305
|
}
|
|
72225
72306
|
}
|
|
72226
72307
|
switch (cmd.type) {
|
|
@@ -72442,7 +72523,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
72442
72523
|
pivot.init({ reload: true });
|
|
72443
72524
|
}
|
|
72444
72525
|
setupPivot(pivotId, { recreate } = { recreate: false }) {
|
|
72445
|
-
const definition = this.getters.getPivotCoreDefinition(pivotId);
|
|
72526
|
+
const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
|
|
72446
72527
|
if (!(pivotId in this.pivots)) {
|
|
72447
72528
|
const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
|
|
72448
72529
|
this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
|
|
@@ -81949,16 +82030,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
81949
82030
|
get clickableCells() {
|
|
81950
82031
|
const cells = [];
|
|
81951
82032
|
const getters = this.getters;
|
|
81952
|
-
const sheetId = getters.getActiveSheetId();
|
|
81953
82033
|
for (const position of this.getters.getVisibleCellPositions()) {
|
|
81954
82034
|
const item = this.getClickableItem(position);
|
|
81955
82035
|
if (!item) {
|
|
81956
82036
|
continue;
|
|
81957
82037
|
}
|
|
81958
82038
|
const title = typeof item.title === "function" ? item.title(position, getters) : item.title;
|
|
81959
|
-
const
|
|
82039
|
+
const rect = this.getClickableCellRect(position);
|
|
82040
|
+
if (!rect) {
|
|
82041
|
+
continue;
|
|
82042
|
+
}
|
|
81960
82043
|
cells.push({
|
|
81961
|
-
coordinates:
|
|
82044
|
+
coordinates: rect,
|
|
81962
82045
|
position,
|
|
81963
82046
|
action: item.execute,
|
|
81964
82047
|
title: title || "",
|
|
@@ -81968,6 +82051,31 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
81968
82051
|
}
|
|
81969
82052
|
return cells;
|
|
81970
82053
|
}
|
|
82054
|
+
getClickableCellRect(position) {
|
|
82055
|
+
const zone = this.getters.expandZone(position.sheetId, positionToZone(position));
|
|
82056
|
+
const clickableRect = this.getters.getVisibleRect(zone);
|
|
82057
|
+
const icons = this.getters.getCellIcons(position);
|
|
82058
|
+
const iconsAtPosition = {
|
|
82059
|
+
center: icons.find((icon) => icon.horizontalAlign === "center"),
|
|
82060
|
+
left: icons.find((icon) => icon.horizontalAlign === "left"),
|
|
82061
|
+
right: icons.find((icon) => icon.horizontalAlign === "right"),
|
|
82062
|
+
};
|
|
82063
|
+
if (iconsAtPosition.center?.onClick) {
|
|
82064
|
+
return undefined;
|
|
82065
|
+
}
|
|
82066
|
+
if (iconsAtPosition.right?.onClick) {
|
|
82067
|
+
const cellRect = this.getters.getRect(zone);
|
|
82068
|
+
const iconRect = this.getters.getCellIconRect(iconsAtPosition.right, cellRect);
|
|
82069
|
+
clickableRect.width -= iconRect.width + iconsAtPosition.right.margin;
|
|
82070
|
+
}
|
|
82071
|
+
if (iconsAtPosition.left?.onClick) {
|
|
82072
|
+
const cellRect = this.getters.getRect(zone);
|
|
82073
|
+
const iconRect = this.getters.getCellIconRect(iconsAtPosition.left, cellRect);
|
|
82074
|
+
clickableRect.x += iconRect.width + iconsAtPosition.left.margin;
|
|
82075
|
+
clickableRect.width -= iconRect.width + iconsAtPosition.left.margin;
|
|
82076
|
+
}
|
|
82077
|
+
return clickableRect;
|
|
82078
|
+
}
|
|
81971
82079
|
}
|
|
81972
82080
|
|
|
81973
82081
|
css /* scss */ `
|
|
@@ -82725,7 +82833,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
82725
82833
|
height: this.focus === "inactive" ? "26px" : "fit-content",
|
|
82726
82834
|
"max-height": `130px`,
|
|
82727
82835
|
}),
|
|
82728
|
-
showAssistant:
|
|
82836
|
+
showAssistant: false, // Hide assistant in small composer as it gets cropped ATM
|
|
82729
82837
|
placeholder: this.composerStore.placeholder,
|
|
82730
82838
|
};
|
|
82731
82839
|
}
|
|
@@ -84217,7 +84325,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
84217
84325
|
document.activeElement?.contains(this.spreadsheetRef.el)) {
|
|
84218
84326
|
this.focusGrid();
|
|
84219
84327
|
}
|
|
84220
|
-
}
|
|
84328
|
+
});
|
|
84221
84329
|
owl.useExternalListener(window, "resize", () => this.render(true));
|
|
84222
84330
|
// For some reason, the wheel event is not properly registered inside templates
|
|
84223
84331
|
// in Chromium-based browsers based on chromium 125
|
|
@@ -89007,9 +89115,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
89007
89115
|
exports.tokenize = tokenize;
|
|
89008
89116
|
|
|
89009
89117
|
|
|
89010
|
-
__info__.version = "19.0.
|
|
89011
|
-
__info__.date = "2025-
|
|
89012
|
-
__info__.hash = "
|
|
89118
|
+
__info__.version = "19.0.15";
|
|
89119
|
+
__info__.date = "2025-12-26T10:19:23.408Z";
|
|
89120
|
+
__info__.hash = "fe625c9";
|
|
89013
89121
|
|
|
89014
89122
|
|
|
89015
89123
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|