@odoo/o-spreadsheet 19.0.12 → 19.0.16
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 +274 -257
- package/dist/o-spreadsheet.d.ts +15 -32
- package/dist/o-spreadsheet.esm.js +274 -257
- package/dist/o-spreadsheet.iife.js +274 -257
- package/dist/o-spreadsheet.iife.min.js +401 -412
- package/dist/o_spreadsheet.css +390 -0
- package/dist/o_spreadsheet.xml +34 -44
- 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
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.0.16
|
|
6
|
+
* @date 2026-01-07T16:21:15.857Z
|
|
7
|
+
* @hash 9f3f13a
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -1895,21 +1895,25 @@ profilesStartingPosition, profiles, zones, toRemove = false) {
|
|
|
1895
1895
|
function profilesContainsZone(profilesStartingPosition, profiles, zone) {
|
|
1896
1896
|
const leftValue = zone.left;
|
|
1897
1897
|
const rightValue = zone.right;
|
|
1898
|
-
const topValue = zone.top;
|
|
1899
|
-
const bottomValue = zone.bottom + 1;
|
|
1900
1898
|
const leftIndex = binaryPredecessorSearch(profilesStartingPosition, leftValue, 0);
|
|
1901
|
-
const rightIndex =
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1899
|
+
const rightIndex = rightValue === undefined
|
|
1900
|
+
? profilesStartingPosition.length - 1
|
|
1901
|
+
: binaryPredecessorSearch(profilesStartingPosition, rightValue, leftIndex);
|
|
1902
|
+
/**
|
|
1903
|
+
* The `profilesStartingPosition` array always contains at least the value `0` at its first position,
|
|
1904
|
+
* ensuring that applying `binaryPredecessorSearch` will always return a valid index.
|
|
1905
|
+
* Therefore, it is not necessary to check if the result of `binaryPredecessorSearch` equals `-1`.
|
|
1906
|
+
*/
|
|
1907
|
+
const topValue = zone.top;
|
|
1908
|
+
const bottomValue = zone.bottom === undefined ? undefined : zone.bottom + 1;
|
|
1905
1909
|
for (let i = leftIndex; i <= rightIndex; i++) {
|
|
1906
1910
|
const profile = profiles.get(profilesStartingPosition[i]);
|
|
1907
|
-
const topPredIndex = binaryPredecessorSearch(profile, topValue, 0
|
|
1908
|
-
const bottomSuccIndex = binarySuccessorSearch(profile, bottomValue, 0, true);
|
|
1911
|
+
const topPredIndex = binaryPredecessorSearch(profile, topValue, 0);
|
|
1909
1912
|
if (topPredIndex === -1 || topPredIndex % 2 !== 0) {
|
|
1910
1913
|
return false;
|
|
1911
1914
|
}
|
|
1912
|
-
|
|
1915
|
+
const bottomSuccIndex = bottomValue === undefined ? profile.length : binarySuccessorSearch(profile, bottomValue, 0);
|
|
1916
|
+
if (topPredIndex + 1 !== bottomSuccIndex) {
|
|
1913
1917
|
return false;
|
|
1914
1918
|
}
|
|
1915
1919
|
}
|
|
@@ -6595,17 +6599,41 @@ function toCriterionDateNumber(dateValue) {
|
|
|
6595
6599
|
const today = DateTime.now();
|
|
6596
6600
|
switch (dateValue) {
|
|
6597
6601
|
case "today":
|
|
6598
|
-
return jsDateToNumber(today);
|
|
6599
|
-
case "yesterday":
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6602
|
+
return Math.floor(jsDateToNumber(today));
|
|
6603
|
+
case "yesterday": {
|
|
6604
|
+
today.setDate(today.getDate() - 1);
|
|
6605
|
+
return Math.floor(jsDateToNumber(today));
|
|
6606
|
+
}
|
|
6607
|
+
case "tomorrow": {
|
|
6608
|
+
today.setDate(today.getDate() + 1);
|
|
6609
|
+
return Math.floor(jsDateToNumber(today));
|
|
6610
|
+
}
|
|
6603
6611
|
case "lastWeek":
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6612
|
+
today.setDate(today.getDate() - 6);
|
|
6613
|
+
return Math.floor(jsDateToNumber(today));
|
|
6614
|
+
case "lastMonth": {
|
|
6615
|
+
const lastMonth = today.getMonth() === 0 ? 11 : today.getMonth() - 1;
|
|
6616
|
+
const dateInLastMonth = new DateTime(today.getFullYear(), lastMonth, 1);
|
|
6617
|
+
if (today.getDate() > getDaysInMonth(dateInLastMonth)) {
|
|
6618
|
+
today.setDate(1);
|
|
6619
|
+
}
|
|
6620
|
+
else {
|
|
6621
|
+
today.setDate(today.getDate() + 1);
|
|
6622
|
+
today.setMonth(today.getMonth() - 1);
|
|
6623
|
+
}
|
|
6624
|
+
return Math.floor(jsDateToNumber(today));
|
|
6625
|
+
}
|
|
6607
6626
|
case "lastYear":
|
|
6608
|
-
|
|
6627
|
+
// Handle leap year case
|
|
6628
|
+
if (today.getMonth() === 1 && today.getDate() === 29) {
|
|
6629
|
+
today.setDate(28);
|
|
6630
|
+
today.setFullYear(today.getFullYear() - 1);
|
|
6631
|
+
}
|
|
6632
|
+
else {
|
|
6633
|
+
today.setDate(today.getDate() + 1);
|
|
6634
|
+
today.setFullYear(today.getFullYear() - 1);
|
|
6635
|
+
}
|
|
6636
|
+
return Math.floor(jsDateToNumber(today));
|
|
6609
6637
|
}
|
|
6610
6638
|
}
|
|
6611
6639
|
/** Get all the dates values of a criterion converted to numbers, converting date values such as "today" to actual dates */
|
|
@@ -6778,67 +6806,6 @@ function getFullReference(sheetName, xc) {
|
|
|
6778
6806
|
return sheetName !== undefined ? `${getCanonicalSymbolName(sheetName)}!${xc}` : xc;
|
|
6779
6807
|
}
|
|
6780
6808
|
|
|
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
6809
|
function createRange(args, getSheetSize) {
|
|
6843
6810
|
const unboundedZone = args.zone;
|
|
6844
6811
|
const zone = boundUnboundedZone(unboundedZone, getSheetSize(args.sheetId));
|
|
@@ -7086,7 +7053,7 @@ function getApplyRangeChangeRemoveColRow(cmd) {
|
|
|
7086
7053
|
elements.sort((a, b) => b - a);
|
|
7087
7054
|
const groups = groupConsecutive(elements);
|
|
7088
7055
|
return (range) => {
|
|
7089
|
-
if (
|
|
7056
|
+
if (range.sheetId !== cmd.sheetId) {
|
|
7090
7057
|
return { changeType: "NONE" };
|
|
7091
7058
|
}
|
|
7092
7059
|
let newRange = range;
|
|
@@ -7293,6 +7260,69 @@ function fuzzyLookup(pattern, list, fn) {
|
|
|
7293
7260
|
return results.map((r) => r.elem);
|
|
7294
7261
|
}
|
|
7295
7262
|
|
|
7263
|
+
function createDefaultRows(rowNumber) {
|
|
7264
|
+
const rows = [];
|
|
7265
|
+
for (let i = 0; i < rowNumber; i++) {
|
|
7266
|
+
const row = {
|
|
7267
|
+
cells: {},
|
|
7268
|
+
};
|
|
7269
|
+
rows.push(row);
|
|
7270
|
+
}
|
|
7271
|
+
return rows;
|
|
7272
|
+
}
|
|
7273
|
+
function moveHeaderIndexesOnHeaderAddition(indexHeaderAdded, numberAdded, headers) {
|
|
7274
|
+
return headers.map((header) => {
|
|
7275
|
+
if (header >= indexHeaderAdded) {
|
|
7276
|
+
return header + numberAdded;
|
|
7277
|
+
}
|
|
7278
|
+
return header;
|
|
7279
|
+
});
|
|
7280
|
+
}
|
|
7281
|
+
function moveHeaderIndexesOnHeaderDeletion(deletedHeaders, headers) {
|
|
7282
|
+
deletedHeaders = [...deletedHeaders].sort((a, b) => b - a);
|
|
7283
|
+
return headers
|
|
7284
|
+
.map((header) => {
|
|
7285
|
+
for (const deletedHeader of deletedHeaders) {
|
|
7286
|
+
if (header > deletedHeader) {
|
|
7287
|
+
header--;
|
|
7288
|
+
}
|
|
7289
|
+
else if (header === deletedHeader) {
|
|
7290
|
+
return undefined;
|
|
7291
|
+
}
|
|
7292
|
+
}
|
|
7293
|
+
return header;
|
|
7294
|
+
})
|
|
7295
|
+
.filter(isDefined);
|
|
7296
|
+
}
|
|
7297
|
+
function getNextSheetName(existingNames, baseName = "Sheet") {
|
|
7298
|
+
let i = 1;
|
|
7299
|
+
let name = `${baseName}${i}`;
|
|
7300
|
+
while (existingNames.includes(name)) {
|
|
7301
|
+
name = `${baseName}${i}`;
|
|
7302
|
+
i++;
|
|
7303
|
+
}
|
|
7304
|
+
return name;
|
|
7305
|
+
}
|
|
7306
|
+
function getDuplicateSheetName(nameToDuplicate, existingNames) {
|
|
7307
|
+
let i = 1;
|
|
7308
|
+
const baseName = _t("Copy of %s", nameToDuplicate);
|
|
7309
|
+
let name = baseName.toString();
|
|
7310
|
+
while (existingNames.includes(name)) {
|
|
7311
|
+
name = `${baseName} (${i})`;
|
|
7312
|
+
i++;
|
|
7313
|
+
}
|
|
7314
|
+
return name;
|
|
7315
|
+
}
|
|
7316
|
+
const toStandardizedSheetName = memoize(function toStandardizedSheetName(name) {
|
|
7317
|
+
return getUnquotedSheetName(name.trim().toUpperCase());
|
|
7318
|
+
});
|
|
7319
|
+
function isSheetNameEqual(name1, name2) {
|
|
7320
|
+
if (name1 === undefined || name2 === undefined) {
|
|
7321
|
+
return false;
|
|
7322
|
+
}
|
|
7323
|
+
return toStandardizedSheetName(name1) === toStandardizedSheetName(name2);
|
|
7324
|
+
}
|
|
7325
|
+
|
|
7296
7326
|
function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
|
|
7297
7327
|
return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
|
|
7298
7328
|
}
|
|
@@ -31421,7 +31451,7 @@ function escapeQueryNameSpaces(query) {
|
|
|
31421
31451
|
return query.replaceAll(/([a-zA-Z0-9]+):([a-zA-Z0-9]+)/g, "NAMESPACE" + "$1" + "NAMESPACE" + "$2");
|
|
31422
31452
|
}
|
|
31423
31453
|
|
|
31424
|
-
function getChartMenuActions(figureId,
|
|
31454
|
+
function getChartMenuActions(figureId, env) {
|
|
31425
31455
|
const chartId = env.model.getters.getChartIdFromFigureId(figureId);
|
|
31426
31456
|
if (!chartId) {
|
|
31427
31457
|
return [];
|
|
@@ -31441,11 +31471,11 @@ function getChartMenuActions(figureId, onFigureDeleted, env) {
|
|
|
31441
31471
|
getCutMenuItem(figureId, env),
|
|
31442
31472
|
getCopyAsImageMenuItem(figureId, env),
|
|
31443
31473
|
getDownloadChartMenuItem(figureId, env),
|
|
31444
|
-
getDeleteMenuItem(figureId,
|
|
31474
|
+
getDeleteMenuItem(figureId, env),
|
|
31445
31475
|
];
|
|
31446
31476
|
return createActions(menuItemSpecs).filter((action) => env.model.getters.isReadonly() ? action.isReadonlyAllowed : true);
|
|
31447
31477
|
}
|
|
31448
|
-
function getImageMenuActions(figureId,
|
|
31478
|
+
function getImageMenuActions(figureId, env) {
|
|
31449
31479
|
const menuItemSpecs = [
|
|
31450
31480
|
getCopyMenuItem(figureId, env, _t("Image copied to clipboard")),
|
|
31451
31481
|
getCutMenuItem(figureId, env),
|
|
@@ -31488,11 +31518,11 @@ function getImageMenuActions(figureId, onFigureDeleted, env) {
|
|
|
31488
31518
|
},
|
|
31489
31519
|
icon: "o-spreadsheet-Icon.DOWNLOAD",
|
|
31490
31520
|
},
|
|
31491
|
-
getDeleteMenuItem(figureId,
|
|
31521
|
+
getDeleteMenuItem(figureId, env),
|
|
31492
31522
|
];
|
|
31493
31523
|
return createActions(menuItemSpecs);
|
|
31494
31524
|
}
|
|
31495
|
-
function getCarouselMenuActions(figureId,
|
|
31525
|
+
function getCarouselMenuActions(figureId, env) {
|
|
31496
31526
|
const isChartSelected = (env) => env.model.getters.getSelectedCarouselItem(figureId)?.type === "chart";
|
|
31497
31527
|
const menuItemSpecs = [
|
|
31498
31528
|
{
|
|
@@ -31511,7 +31541,7 @@ function getCarouselMenuActions(figureId, onFigureDeleted, env) {
|
|
|
31511
31541
|
},
|
|
31512
31542
|
{ ...getCutMenuItem(figureId, env), name: _t("Cut carousel") },
|
|
31513
31543
|
{
|
|
31514
|
-
...getDeleteMenuItem(figureId,
|
|
31544
|
+
...getDeleteMenuItem(figureId, env),
|
|
31515
31545
|
name: _t("Delete carousel"),
|
|
31516
31546
|
separator: true,
|
|
31517
31547
|
},
|
|
@@ -31654,7 +31684,7 @@ function getDownloadChartMenuItem(figureId, env) {
|
|
|
31654
31684
|
isReadonlyAllowed: true,
|
|
31655
31685
|
};
|
|
31656
31686
|
}
|
|
31657
|
-
function getDeleteMenuItem(figureId,
|
|
31687
|
+
function getDeleteMenuItem(figureId, env) {
|
|
31658
31688
|
return {
|
|
31659
31689
|
id: "delete",
|
|
31660
31690
|
name: _t("Delete"),
|
|
@@ -31663,7 +31693,6 @@ function getDeleteMenuItem(figureId, onFigureDeleted, env) {
|
|
|
31663
31693
|
sheetId: env.model.getters.getActiveSheetId(),
|
|
31664
31694
|
figureId,
|
|
31665
31695
|
});
|
|
31666
|
-
onFigureDeleted();
|
|
31667
31696
|
},
|
|
31668
31697
|
icon: "o-spreadsheet-Icon.TRASH",
|
|
31669
31698
|
};
|
|
@@ -32476,7 +32505,7 @@ class ChartDashboardMenu extends owl.Component {
|
|
|
32476
32505
|
this.menuState.isOpen = true;
|
|
32477
32506
|
this.menuState.anchorRect = getBoundingRectAsPOJO(ev.currentTarget);
|
|
32478
32507
|
const figureId = this.env.model.getters.getFigureIdFromChartId(this.props.chartId);
|
|
32479
|
-
this.menuState.menuItems = getChartMenuActions(figureId,
|
|
32508
|
+
this.menuState.menuItems = getChartMenuActions(figureId, this.env);
|
|
32480
32509
|
}
|
|
32481
32510
|
get fullScreenMenuItem() {
|
|
32482
32511
|
if (!this.props.hasFullScreenButton) {
|
|
@@ -32503,7 +32532,6 @@ class CarouselFigure extends owl.Component {
|
|
|
32503
32532
|
static template = "o-spreadsheet-CarouselFigure";
|
|
32504
32533
|
static props = {
|
|
32505
32534
|
figureUI: Object,
|
|
32506
|
-
onFigureDeleted: Function,
|
|
32507
32535
|
editFigureStyle: { type: Function, optional: true },
|
|
32508
32536
|
isFullScreen: { type: Boolean, optional: true },
|
|
32509
32537
|
openContextMenu: { type: Function, optional: true },
|
|
@@ -32652,7 +32680,6 @@ class ChartFigure extends owl.Component {
|
|
|
32652
32680
|
static template = "o-spreadsheet-ChartFigure";
|
|
32653
32681
|
static props = {
|
|
32654
32682
|
figureUI: Object,
|
|
32655
|
-
onFigureDeleted: Function,
|
|
32656
32683
|
editFigureStyle: { type: Function, optional: true },
|
|
32657
32684
|
isFullScreen: { type: Boolean, optional: true },
|
|
32658
32685
|
openContextMenu: { type: Function, optional: true },
|
|
@@ -32686,7 +32713,6 @@ class ImageFigure extends owl.Component {
|
|
|
32686
32713
|
static template = "o-spreadsheet-ImageFigure";
|
|
32687
32714
|
static props = {
|
|
32688
32715
|
figureUI: Object,
|
|
32689
|
-
onFigureDeleted: Function,
|
|
32690
32716
|
editFigureStyle: { type: Function, optional: true },
|
|
32691
32717
|
openContextMenu: { type: Function, optional: true },
|
|
32692
32718
|
};
|
|
@@ -32805,13 +32831,11 @@ class FigureComponent extends owl.Component {
|
|
|
32805
32831
|
figureUI: Object,
|
|
32806
32832
|
style: { type: String, optional: true },
|
|
32807
32833
|
class: { type: String, optional: true },
|
|
32808
|
-
onFigureDeleted: { type: Function, optional: true },
|
|
32809
32834
|
onMouseDown: { type: Function, optional: true },
|
|
32810
32835
|
onClickAnchor: { type: Function, optional: true },
|
|
32811
32836
|
};
|
|
32812
32837
|
static components = { MenuPopover };
|
|
32813
32838
|
static defaultProps = {
|
|
32814
|
-
onFigureDeleted: () => { },
|
|
32815
32839
|
onMouseDown: () => { },
|
|
32816
32840
|
onClickAnchor: () => { },
|
|
32817
32841
|
};
|
|
@@ -32889,9 +32913,6 @@ class FigureComponent extends owl.Component {
|
|
|
32889
32913
|
this.props.figureUI.id,
|
|
32890
32914
|
this.figureRef.el,
|
|
32891
32915
|
]);
|
|
32892
|
-
owl.onWillUnmount(() => {
|
|
32893
|
-
this.props.onFigureDeleted();
|
|
32894
|
-
});
|
|
32895
32916
|
}
|
|
32896
32917
|
clickAnchor(dirX, dirY, ev) {
|
|
32897
32918
|
this.props.onClickAnchor(dirX, dirY, ev);
|
|
@@ -32915,7 +32936,6 @@ class FigureComponent extends owl.Component {
|
|
|
32915
32936
|
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
32916
32937
|
figureId: this.props.figureUI.id,
|
|
32917
32938
|
});
|
|
32918
|
-
this.props.onFigureDeleted();
|
|
32919
32939
|
ev.preventDefault();
|
|
32920
32940
|
ev.stopPropagation();
|
|
32921
32941
|
break;
|
|
@@ -33008,7 +33028,7 @@ class FigureComponent extends owl.Component {
|
|
|
33008
33028
|
this.menuState.anchorRect = anchorRect;
|
|
33009
33029
|
this.menuState.menuItems = figureRegistry
|
|
33010
33030
|
.get(this.props.figureUI.tag)
|
|
33011
|
-
.menuBuilder(this.props.figureUI.id, this.
|
|
33031
|
+
.menuBuilder(this.props.figureUI.id, this.env);
|
|
33012
33032
|
}
|
|
33013
33033
|
editWrapperStyle(properties) {
|
|
33014
33034
|
if (this.figureWrapperRef.el) {
|
|
@@ -33380,7 +33400,7 @@ criterionEvaluatorRegistry.add("dateIs", {
|
|
|
33380
33400
|
return false;
|
|
33381
33401
|
}
|
|
33382
33402
|
if (["lastWeek", "lastMonth", "lastYear"].includes(criterion.dateValue)) {
|
|
33383
|
-
const today =
|
|
33403
|
+
const today = Math.floor(jsDateToNumber(DateTime.now()));
|
|
33384
33404
|
return isDateBetween(dateValue, today, criterionValue);
|
|
33385
33405
|
}
|
|
33386
33406
|
return areDatesSameDay(dateValue, criterionValue);
|
|
@@ -37494,6 +37514,12 @@ class SelectionInput extends owl.Component {
|
|
|
37494
37514
|
}
|
|
37495
37515
|
setup() {
|
|
37496
37516
|
owl.useEffect(() => this.focusedInput.el?.focus(), () => [this.focusedInput.el]);
|
|
37517
|
+
owl.useEffect(() => {
|
|
37518
|
+
// Check the offsetParent to know if the input or an ancestor is `display: none` (eg. when changing side panel tab)
|
|
37519
|
+
if (this.store.hasFocus && this.selectionRef.el?.offsetParent === null) {
|
|
37520
|
+
this.reset();
|
|
37521
|
+
}
|
|
37522
|
+
});
|
|
37497
37523
|
this.store = useLocalStore(SelectionInputStore, this.props.ranges, this.props.hasSingleRange || false, this.props.colors, this.props.disabledRanges);
|
|
37498
37524
|
owl.onWillUpdateProps((nextProps) => {
|
|
37499
37525
|
if (nextProps.ranges.join() !== this.store.selectionInputValues.join()) {
|
|
@@ -45277,7 +45303,7 @@ class FormulaFingerprintStore extends SpreadsheetStore {
|
|
|
45277
45303
|
const leftOffset = isLeftUnbounded || left?.colFixed ? 0 : colCellOffset;
|
|
45278
45304
|
const topOffset = isTopUnbounded || left?.rowFixed ? 0 : rowCellOffset;
|
|
45279
45305
|
const isRightFixed = (!right && left?.colFixed) || right?.colFixed;
|
|
45280
|
-
const isBottomFixed = (!right && left
|
|
45306
|
+
const isBottomFixed = (!right && left?.rowFixed) || right?.rowFixed;
|
|
45281
45307
|
const isRightUnbounded = range.unboundedZone.right === undefined;
|
|
45282
45308
|
const isBottomUnbounded = range.unboundedZone.bottom === undefined;
|
|
45283
45309
|
const rightOffset = isRightUnbounded || isRightFixed ? 0 : colCellOffset;
|
|
@@ -47841,7 +47867,37 @@ pivotRegistry.add("SPREADSHEET", {
|
|
|
47841
47867
|
isMeasureCandidate: (field) => field.type !== "boolean",
|
|
47842
47868
|
isGroupable: () => true,
|
|
47843
47869
|
canHaveCustomGroup: (field) => field.type === "char" && !field.isCustomField,
|
|
47870
|
+
adaptRanges: (getters, definition, applyChange) => {
|
|
47871
|
+
if (definition.type !== "SPREADSHEET" || !definition.dataSet) {
|
|
47872
|
+
return definition;
|
|
47873
|
+
}
|
|
47874
|
+
const { sheetId, zone } = definition.dataSet;
|
|
47875
|
+
const range = getters.getRangeFromZone(sheetId, zone);
|
|
47876
|
+
const adaptedRange = adaptPivotRange(range, applyChange);
|
|
47877
|
+
if (adaptedRange === range) {
|
|
47878
|
+
return definition;
|
|
47879
|
+
}
|
|
47880
|
+
const dataSet = adaptedRange && {
|
|
47881
|
+
sheetId: adaptedRange.sheetId,
|
|
47882
|
+
zone: adaptedRange.zone,
|
|
47883
|
+
};
|
|
47884
|
+
return { ...definition, dataSet };
|
|
47885
|
+
},
|
|
47844
47886
|
});
|
|
47887
|
+
function adaptPivotRange(range, applyChange) {
|
|
47888
|
+
if (!range) {
|
|
47889
|
+
return undefined;
|
|
47890
|
+
}
|
|
47891
|
+
const change = applyChange(range);
|
|
47892
|
+
switch (change.changeType) {
|
|
47893
|
+
case "NONE":
|
|
47894
|
+
return range;
|
|
47895
|
+
case "REMOVE":
|
|
47896
|
+
return undefined;
|
|
47897
|
+
default:
|
|
47898
|
+
return change.range;
|
|
47899
|
+
}
|
|
47900
|
+
}
|
|
47845
47901
|
|
|
47846
47902
|
const pivotProperties = {
|
|
47847
47903
|
name: _t("See pivot properties"),
|
|
@@ -49112,7 +49168,6 @@ class ArrayFormulaHighlight extends SpreadsheetStore {
|
|
|
49112
49168
|
}
|
|
49113
49169
|
get highlights() {
|
|
49114
49170
|
const position = this.model.getters.getActivePosition();
|
|
49115
|
-
const cell = this.getters.getEvaluatedCell(position);
|
|
49116
49171
|
const spreader = this.model.getters.getArrayFormulaSpreadingOn(position);
|
|
49117
49172
|
const zone = spreader
|
|
49118
49173
|
? this.model.getters.getSpreadZone(spreader, { ignoreSpillError: true })
|
|
@@ -49120,10 +49175,11 @@ class ArrayFormulaHighlight extends SpreadsheetStore {
|
|
|
49120
49175
|
if (!zone) {
|
|
49121
49176
|
return [];
|
|
49122
49177
|
}
|
|
49178
|
+
const isArrayFormulaBlocked = this.model.getters.isArrayFormulaSpillBlocked(spreader ?? position);
|
|
49123
49179
|
return [
|
|
49124
49180
|
{
|
|
49125
49181
|
range: this.model.getters.getRangeFromZone(position.sheetId, zone),
|
|
49126
|
-
dashed:
|
|
49182
|
+
dashed: isArrayFormulaBlocked,
|
|
49127
49183
|
color: "#17A2B8",
|
|
49128
49184
|
noFill: true,
|
|
49129
49185
|
thinLine: true,
|
|
@@ -50530,9 +50586,7 @@ css /*SCSS*/ `
|
|
|
50530
50586
|
*/
|
|
50531
50587
|
class FiguresContainer extends owl.Component {
|
|
50532
50588
|
static template = "o-spreadsheet-FiguresContainer";
|
|
50533
|
-
static props = {
|
|
50534
|
-
onFigureDeleted: Function,
|
|
50535
|
-
};
|
|
50589
|
+
static props = {};
|
|
50536
50590
|
static components = { FigureComponent };
|
|
50537
50591
|
dnd = owl.useState({
|
|
50538
50592
|
draggedFigure: undefined,
|
|
@@ -50742,7 +50796,6 @@ class FiguresContainer extends owl.Component {
|
|
|
50742
50796
|
carouselFigureId: this.dnd.overlappingCarousel.id,
|
|
50743
50797
|
chartFigureId: figureUI.id,
|
|
50744
50798
|
});
|
|
50745
|
-
this.props.onFigureDeleted();
|
|
50746
50799
|
}
|
|
50747
50800
|
this.dnd.draggedFigure = undefined;
|
|
50748
50801
|
this.dnd.horizontalSnap = undefined;
|
|
@@ -50968,16 +51021,16 @@ css /* scss */ `
|
|
|
50968
51021
|
`;
|
|
50969
51022
|
class GridAddRowsFooter extends owl.Component {
|
|
50970
51023
|
static template = "o-spreadsheet-GridAddRowsFooter";
|
|
50971
|
-
static props = {
|
|
50972
|
-
focusGrid: Function,
|
|
50973
|
-
};
|
|
51024
|
+
static props = {};
|
|
50974
51025
|
static components = { ValidationMessages };
|
|
51026
|
+
DOMFocusableElementStore;
|
|
50975
51027
|
inputRef = owl.useRef("inputRef");
|
|
50976
51028
|
state = owl.useState({
|
|
50977
51029
|
inputValue: "100",
|
|
50978
51030
|
errorFlag: false,
|
|
50979
51031
|
});
|
|
50980
51032
|
setup() {
|
|
51033
|
+
this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
|
|
50981
51034
|
owl.useExternalListener(window, "click", this.onExternalClick, { capture: true });
|
|
50982
51035
|
}
|
|
50983
51036
|
get addRowsPosition() {
|
|
@@ -50995,7 +51048,7 @@ class GridAddRowsFooter extends owl.Component {
|
|
|
50995
51048
|
}
|
|
50996
51049
|
onKeydown(ev) {
|
|
50997
51050
|
if (ev.key.toUpperCase() === "ESCAPE") {
|
|
50998
|
-
this.
|
|
51051
|
+
this.focusDefaultElement();
|
|
50999
51052
|
}
|
|
51000
51053
|
else if (ev.key.toUpperCase() === "ENTER") {
|
|
51001
51054
|
this.onConfirm();
|
|
@@ -51022,7 +51075,7 @@ class GridAddRowsFooter extends owl.Component {
|
|
|
51022
51075
|
quantity,
|
|
51023
51076
|
dimension: "ROW",
|
|
51024
51077
|
});
|
|
51025
|
-
this.
|
|
51078
|
+
this.focusDefaultElement();
|
|
51026
51079
|
// After adding new rows, scroll down to the new last row
|
|
51027
51080
|
const { scrollX } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
51028
51081
|
const { end } = this.env.model.getters.getRowDimensions(activeSheetId, rowNumber + quantity - 1);
|
|
@@ -51035,7 +51088,12 @@ class GridAddRowsFooter extends owl.Component {
|
|
|
51035
51088
|
if (this.inputRef.el !== document.activeElement || ev.target === this.inputRef.el) {
|
|
51036
51089
|
return;
|
|
51037
51090
|
}
|
|
51038
|
-
this.
|
|
51091
|
+
this.focusDefaultElement();
|
|
51092
|
+
}
|
|
51093
|
+
focusDefaultElement() {
|
|
51094
|
+
if (document.activeElement === this.inputRef.el) {
|
|
51095
|
+
this.DOMFocusableElementStore.focus();
|
|
51096
|
+
}
|
|
51039
51097
|
}
|
|
51040
51098
|
}
|
|
51041
51099
|
|
|
@@ -51310,11 +51368,9 @@ class GridOverlay extends owl.Component {
|
|
|
51310
51368
|
onCellClicked: { type: Function, optional: true },
|
|
51311
51369
|
onCellRightClicked: { type: Function, optional: true },
|
|
51312
51370
|
onGridResized: { type: Function, optional: true },
|
|
51313
|
-
onFigureDeleted: { type: Function, optional: true },
|
|
51314
51371
|
onGridMoved: Function,
|
|
51315
51372
|
gridOverlayDimensions: String,
|
|
51316
51373
|
slots: { type: Object, optional: true },
|
|
51317
|
-
getGridSize: Function,
|
|
51318
51374
|
};
|
|
51319
51375
|
static components = {
|
|
51320
51376
|
FiguresContainer,
|
|
@@ -51325,7 +51381,6 @@ class GridOverlay extends owl.Component {
|
|
|
51325
51381
|
onCellClicked: () => { },
|
|
51326
51382
|
onCellRightClicked: () => { },
|
|
51327
51383
|
onGridResized: () => { },
|
|
51328
|
-
onFigureDeleted: () => { },
|
|
51329
51384
|
};
|
|
51330
51385
|
gridOverlay = owl.useRef("gridOverlay");
|
|
51331
51386
|
cellPopovers;
|
|
@@ -51334,14 +51389,7 @@ class GridOverlay extends owl.Component {
|
|
|
51334
51389
|
setup() {
|
|
51335
51390
|
useCellHovered(this.env, this.gridOverlay);
|
|
51336
51391
|
const resizeObserver = new ResizeObserver(() => {
|
|
51337
|
-
|
|
51338
|
-
const { width, height } = this.props.getGridSize();
|
|
51339
|
-
this.props.onGridResized({
|
|
51340
|
-
x: boundingRect.left,
|
|
51341
|
-
y: boundingRect.top,
|
|
51342
|
-
height: height,
|
|
51343
|
-
width: width,
|
|
51344
|
-
});
|
|
51392
|
+
this.props.onGridResized();
|
|
51345
51393
|
});
|
|
51346
51394
|
owl.onMounted(() => {
|
|
51347
51395
|
resizeObserver.observe(this.gridOverlayEl);
|
|
@@ -56591,7 +56639,7 @@ function useHighlights(highlightProvider) {
|
|
|
56591
56639
|
}
|
|
56592
56640
|
|
|
56593
56641
|
css /* scss */ `
|
|
56594
|
-
.o-cf-preview {
|
|
56642
|
+
.o-spreadsheet .o-cf-preview {
|
|
56595
56643
|
&.o-cf-cursor-ptr {
|
|
56596
56644
|
cursor: pointer;
|
|
56597
56645
|
}
|
|
@@ -56599,6 +56647,7 @@ css /* scss */ `
|
|
|
56599
56647
|
border-bottom: 1px solid ${GRAY_300};
|
|
56600
56648
|
height: 80px;
|
|
56601
56649
|
padding: 10px;
|
|
56650
|
+
box-sizing: border-box;
|
|
56602
56651
|
position: relative;
|
|
56603
56652
|
cursor: pointer;
|
|
56604
56653
|
&:hover,
|
|
@@ -56612,7 +56661,6 @@ css /* scss */ `
|
|
|
56612
56661
|
.o-cf-preview-icon {
|
|
56613
56662
|
border: 1px solid ${GRAY_300};
|
|
56614
56663
|
background-color: #fff;
|
|
56615
|
-
position: absolute;
|
|
56616
56664
|
height: 50px;
|
|
56617
56665
|
width: 50px;
|
|
56618
56666
|
.o-icon {
|
|
@@ -56621,12 +56669,6 @@ css /* scss */ `
|
|
|
56621
56669
|
}
|
|
56622
56670
|
}
|
|
56623
56671
|
.o-cf-preview-description {
|
|
56624
|
-
left: 65px;
|
|
56625
|
-
margin-bottom: auto;
|
|
56626
|
-
margin-right: 8px;
|
|
56627
|
-
margin-top: auto;
|
|
56628
|
-
position: relative;
|
|
56629
|
-
width: 142px;
|
|
56630
56672
|
.o-cf-preview-description-rule {
|
|
56631
56673
|
margin-bottom: 4px;
|
|
56632
56674
|
max-height: 2.8em;
|
|
@@ -56636,16 +56678,11 @@ css /* scss */ `
|
|
|
56636
56678
|
font-size: 12px;
|
|
56637
56679
|
}
|
|
56638
56680
|
}
|
|
56639
|
-
.o-cf-delete {
|
|
56640
|
-
left: 90%;
|
|
56641
|
-
top: 39%;
|
|
56642
|
-
position: absolute;
|
|
56643
|
-
}
|
|
56644
56681
|
&:not(:hover):not(.o-cf-dragging) .o-cf-drag-handle {
|
|
56645
56682
|
display: none !important;
|
|
56646
56683
|
}
|
|
56647
56684
|
.o-cf-drag-handle {
|
|
56648
|
-
left:
|
|
56685
|
+
left: 2px;
|
|
56649
56686
|
cursor: move;
|
|
56650
56687
|
.o-icon {
|
|
56651
56688
|
width: 6px;
|
|
@@ -61376,7 +61413,8 @@ class Grid extends owl.Component {
|
|
|
61376
61413
|
});
|
|
61377
61414
|
return !(rect.width === 0 || rect.height === 0);
|
|
61378
61415
|
}
|
|
61379
|
-
onGridResized(
|
|
61416
|
+
onGridResized() {
|
|
61417
|
+
const { height, width } = this.props.getGridSize();
|
|
61380
61418
|
this.env.model.dispatch("RESIZE_SHEETVIEW", {
|
|
61381
61419
|
width: width - HEADER_WIDTH,
|
|
61382
61420
|
height: height - HEADER_HEIGHT,
|
|
@@ -62450,10 +62488,10 @@ class BordersPlugin extends CorePlugin {
|
|
|
62450
62488
|
// existingBorderSideToClear[side] = true means we should clear the border on that
|
|
62451
62489
|
// side of the existing adjacent zone before adding the new border.
|
|
62452
62490
|
const existingBorderSideToClear = {
|
|
62453
|
-
left:
|
|
62454
|
-
right:
|
|
62455
|
-
top:
|
|
62456
|
-
bottom:
|
|
62491
|
+
left: !!newBorder?.right,
|
|
62492
|
+
right: !!newBorder?.left,
|
|
62493
|
+
top: !!newBorder?.bottom,
|
|
62494
|
+
bottom: !!newBorder?.top,
|
|
62457
62495
|
};
|
|
62458
62496
|
let editingZone = [zone];
|
|
62459
62497
|
for (const existingBorder of this.borders[sheetId] ?? []) {
|
|
@@ -65446,6 +65484,7 @@ function rangeToMerge(mergeId, range) {
|
|
|
65446
65484
|
class RangeAdapter {
|
|
65447
65485
|
getters;
|
|
65448
65486
|
providers = [];
|
|
65487
|
+
isAdaptingRanges = false;
|
|
65449
65488
|
constructor(getters) {
|
|
65450
65489
|
this.getters = getters;
|
|
65451
65490
|
}
|
|
@@ -65477,6 +65516,9 @@ class RangeAdapter {
|
|
|
65477
65516
|
}
|
|
65478
65517
|
beforeHandle(command) { }
|
|
65479
65518
|
handle(cmd) {
|
|
65519
|
+
if (this.isAdaptingRanges) {
|
|
65520
|
+
throw new Error("Plugins cannot dispatch commands during adaptRanges phase");
|
|
65521
|
+
}
|
|
65480
65522
|
const rangeAdapter = getRangeAdapter(cmd);
|
|
65481
65523
|
if (rangeAdapter?.applyChange) {
|
|
65482
65524
|
this.executeOnAllRanges(rangeAdapter.applyChange, rangeAdapter.sheetId, rangeAdapter.sheetName);
|
|
@@ -65499,10 +65541,12 @@ class RangeAdapter {
|
|
|
65499
65541
|
};
|
|
65500
65542
|
}
|
|
65501
65543
|
executeOnAllRanges(adaptRange, sheetId, sheetName) {
|
|
65544
|
+
this.isAdaptingRanges = true;
|
|
65502
65545
|
const func = this.verifyRangeRemoved(adaptRange);
|
|
65503
65546
|
for (const provider of this.providers) {
|
|
65504
65547
|
provider(func, sheetId, sheetName);
|
|
65505
65548
|
}
|
|
65549
|
+
this.isAdaptingRanges = false;
|
|
65506
65550
|
}
|
|
65507
65551
|
/**
|
|
65508
65552
|
* Stores the functions bound to each plugin to be able to iterate over all ranges of the application,
|
|
@@ -65819,7 +65863,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
65819
65863
|
break;
|
|
65820
65864
|
case "CREATE_SHEET":
|
|
65821
65865
|
const sheet = this.createSheet(cmd.sheetId, cmd.name || this.getNextSheetName(), cmd.cols || 26, cmd.rows || 100, cmd.position);
|
|
65822
|
-
this.history.update("sheetIdsMapName", sheet.name, sheet.id);
|
|
65866
|
+
this.history.update("sheetIdsMapName", toStandardizedSheetName(sheet.name), sheet.id);
|
|
65823
65867
|
break;
|
|
65824
65868
|
case "MOVE_SHEET":
|
|
65825
65869
|
this.moveSheet(cmd.sheetId, cmd.delta);
|
|
@@ -65886,7 +65930,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
65886
65930
|
// that depends on a sheet not already imported will not be able to be
|
|
65887
65931
|
// compiled
|
|
65888
65932
|
for (const sheet of data.sheets) {
|
|
65889
|
-
this.sheetIdsMapName[sheet.name] = sheet.id;
|
|
65933
|
+
this.sheetIdsMapName[toStandardizedSheetName(sheet.name)] = sheet.id;
|
|
65890
65934
|
}
|
|
65891
65935
|
for (const sheetData of data.sheets) {
|
|
65892
65936
|
const name = sheetData.name || "Sheet" + (Object.keys(this.sheets).length + 1);
|
|
@@ -65976,12 +66020,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
65976
66020
|
}
|
|
65977
66021
|
getSheetIdByName(name) {
|
|
65978
66022
|
if (name) {
|
|
65979
|
-
|
|
65980
|
-
for (const key in this.sheetIdsMapName) {
|
|
65981
|
-
if (isSheetNameEqual(key, unquotedName)) {
|
|
65982
|
-
return this.sheetIdsMapName[key];
|
|
65983
|
-
}
|
|
65984
|
-
}
|
|
66023
|
+
return this.sheetIdsMapName[toStandardizedSheetName(name)];
|
|
65985
66024
|
}
|
|
65986
66025
|
return undefined;
|
|
65987
66026
|
}
|
|
@@ -66281,8 +66320,8 @@ class SheetPlugin extends CorePlugin {
|
|
|
66281
66320
|
const oldName = sheet.name;
|
|
66282
66321
|
this.history.update("sheets", sheet.id, "name", name.trim());
|
|
66283
66322
|
const sheetIdsMapName = Object.assign({}, this.sheetIdsMapName);
|
|
66284
|
-
delete sheetIdsMapName[oldName];
|
|
66285
|
-
sheetIdsMapName[name] = sheet.id;
|
|
66323
|
+
delete sheetIdsMapName[toStandardizedSheetName(oldName)];
|
|
66324
|
+
sheetIdsMapName[toStandardizedSheetName(name)] = sheet.id;
|
|
66286
66325
|
this.history.update("sheetIdsMapName", sheetIdsMapName);
|
|
66287
66326
|
}
|
|
66288
66327
|
hideSheet(sheetId) {
|
|
@@ -66320,7 +66359,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
66320
66359
|
});
|
|
66321
66360
|
}
|
|
66322
66361
|
const sheetIdsMapName = Object.assign({}, this.sheetIdsMapName);
|
|
66323
|
-
sheetIdsMapName[newSheet.name] = newSheet.id;
|
|
66362
|
+
sheetIdsMapName[toStandardizedSheetName(newSheet.name)] = newSheet.id;
|
|
66324
66363
|
this.history.update("sheetIdsMapName", sheetIdsMapName);
|
|
66325
66364
|
}
|
|
66326
66365
|
getDuplicateSheetName(sheetName) {
|
|
@@ -66337,7 +66376,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
66337
66376
|
orderedSheetIds.splice(currentIndex, 1);
|
|
66338
66377
|
this.history.update("orderedSheetIds", orderedSheetIds);
|
|
66339
66378
|
const sheetIdsMapName = Object.assign({}, this.sheetIdsMapName);
|
|
66340
|
-
delete sheetIdsMapName[name];
|
|
66379
|
+
delete sheetIdsMapName[toStandardizedSheetName(name)];
|
|
66341
66380
|
this.history.update("sheetIdsMapName", sheetIdsMapName);
|
|
66342
66381
|
}
|
|
66343
66382
|
/**
|
|
@@ -67657,6 +67696,18 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
67657
67696
|
}
|
|
67658
67697
|
}
|
|
67659
67698
|
adaptRanges(applyChange) {
|
|
67699
|
+
for (const pivotId in this.pivots) {
|
|
67700
|
+
const definition = deepCopy(this.pivots[pivotId]?.definition);
|
|
67701
|
+
if (!definition) {
|
|
67702
|
+
continue;
|
|
67703
|
+
}
|
|
67704
|
+
const newDefinition = pivotRegistry
|
|
67705
|
+
.get(definition.type)
|
|
67706
|
+
?.adaptRanges?.(this.getters, definition, applyChange);
|
|
67707
|
+
if (newDefinition && !deepEquals(definition, newDefinition)) {
|
|
67708
|
+
this.history.update("pivots", pivotId, "definition", newDefinition);
|
|
67709
|
+
}
|
|
67710
|
+
}
|
|
67660
67711
|
for (const sheetId in this.compiledMeasureFormulas) {
|
|
67661
67712
|
for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
|
|
67662
67713
|
const compiledFormula = this.compiledMeasureFormulas[sheetId][formulaString];
|
|
@@ -67801,17 +67852,10 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
67801
67852
|
if (!pivot) {
|
|
67802
67853
|
continue;
|
|
67803
67854
|
}
|
|
67804
|
-
const
|
|
67805
|
-
for (const measure of def.measures) {
|
|
67855
|
+
for (const measure of pivot.definition.measures) {
|
|
67806
67856
|
if (measure.computedBy?.formula === formulaString) {
|
|
67807
|
-
const measureIndex =
|
|
67808
|
-
|
|
67809
|
-
def.measures[measureIndex].computedBy = {
|
|
67810
|
-
formula: newFormulaString,
|
|
67811
|
-
sheetId,
|
|
67812
|
-
};
|
|
67813
|
-
}
|
|
67814
|
-
this.dispatch("UPDATE_PIVOT", { pivotId, pivot: def });
|
|
67857
|
+
const measureIndex = pivot.definition.measures.indexOf(measure);
|
|
67858
|
+
this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", { formula: newFormulaString, sheetId });
|
|
67815
67859
|
}
|
|
67816
67860
|
}
|
|
67817
67861
|
}
|
|
@@ -67938,20 +67982,6 @@ class SettingsPlugin extends CorePlugin {
|
|
|
67938
67982
|
}
|
|
67939
67983
|
}
|
|
67940
67984
|
|
|
67941
|
-
function adaptPivotRange(range, applyChange) {
|
|
67942
|
-
if (!range) {
|
|
67943
|
-
return undefined;
|
|
67944
|
-
}
|
|
67945
|
-
const change = applyChange(range);
|
|
67946
|
-
switch (change.changeType) {
|
|
67947
|
-
case "NONE":
|
|
67948
|
-
return range;
|
|
67949
|
-
case "REMOVE":
|
|
67950
|
-
return undefined;
|
|
67951
|
-
default:
|
|
67952
|
-
return change.range;
|
|
67953
|
-
}
|
|
67954
|
-
}
|
|
67955
67985
|
class SpreadsheetPivotCorePlugin extends CorePlugin {
|
|
67956
67986
|
allowDispatch(cmd) {
|
|
67957
67987
|
switch (cmd.type) {
|
|
@@ -67962,27 +67992,6 @@ class SpreadsheetPivotCorePlugin extends CorePlugin {
|
|
|
67962
67992
|
}
|
|
67963
67993
|
return "Success" /* CommandResult.Success */;
|
|
67964
67994
|
}
|
|
67965
|
-
adaptRanges(applyChange) {
|
|
67966
|
-
for (const pivotId of this.getters.getPivotIds()) {
|
|
67967
|
-
const definition = this.getters.getPivotCoreDefinition(pivotId);
|
|
67968
|
-
if (definition.type !== "SPREADSHEET") {
|
|
67969
|
-
continue;
|
|
67970
|
-
}
|
|
67971
|
-
if (definition.dataSet) {
|
|
67972
|
-
const { sheetId, zone } = definition.dataSet;
|
|
67973
|
-
const range = this.getters.getRangeFromZone(sheetId, zone);
|
|
67974
|
-
const adaptedRange = adaptPivotRange(range, applyChange);
|
|
67975
|
-
if (adaptedRange === range) {
|
|
67976
|
-
return;
|
|
67977
|
-
}
|
|
67978
|
-
const dataSet = adaptedRange && {
|
|
67979
|
-
sheetId: adaptedRange.sheetId,
|
|
67980
|
-
zone: adaptedRange.zone,
|
|
67981
|
-
};
|
|
67982
|
-
this.dispatch("UPDATE_PIVOT", { pivotId, pivot: { ...definition, dataSet } });
|
|
67983
|
-
}
|
|
67984
|
-
}
|
|
67985
|
-
}
|
|
67986
67995
|
checkDataSetValidity(definition) {
|
|
67987
67996
|
if (definition.type === "SPREADSHEET" && definition.dataSet) {
|
|
67988
67997
|
const { zone, sheetId } = definition.dataSet;
|
|
@@ -68981,13 +68990,6 @@ class ZoneSet {
|
|
|
68981
68990
|
}
|
|
68982
68991
|
return result;
|
|
68983
68992
|
}
|
|
68984
|
-
size() {
|
|
68985
|
-
let size = 0;
|
|
68986
|
-
for (const profile of this.profiles.values()) {
|
|
68987
|
-
size += profile.length;
|
|
68988
|
-
}
|
|
68989
|
-
return size / 2;
|
|
68990
|
-
}
|
|
68991
68993
|
/**
|
|
68992
68994
|
* iterator of all the zones in the ZoneSet
|
|
68993
68995
|
*/
|
|
@@ -69069,13 +69071,6 @@ class RangeSet {
|
|
|
69069
69071
|
clear() {
|
|
69070
69072
|
this.setsBySheetId = {};
|
|
69071
69073
|
}
|
|
69072
|
-
size() {
|
|
69073
|
-
let size = 0;
|
|
69074
|
-
for (const sheetId in this.setsBySheetId) {
|
|
69075
|
-
size += this.setsBySheetId[sheetId].size();
|
|
69076
|
-
}
|
|
69077
|
-
return size;
|
|
69078
|
-
}
|
|
69079
69074
|
isEmpty() {
|
|
69080
69075
|
for (const sheetId in this.setsBySheetId) {
|
|
69081
69076
|
if (!this.setsBySheetId[sheetId].isEmpty()) {
|
|
@@ -69579,6 +69574,9 @@ class Evaluator {
|
|
|
69579
69574
|
const arrayFormulas = this.spreadingRelations.searchFormulaPositionsSpreadingOn(position.sheetId, positionToZone(position));
|
|
69580
69575
|
return arrayFormulas.find((position) => !this.blockedArrayFormulas.has(position));
|
|
69581
69576
|
}
|
|
69577
|
+
isArrayFormulaSpillBlocked(position) {
|
|
69578
|
+
return this.blockedArrayFormulas.has(position);
|
|
69579
|
+
}
|
|
69582
69580
|
updateDependencies(position) {
|
|
69583
69581
|
// removing dependencies is slow because it requires
|
|
69584
69582
|
// to traverse the entire r-tree.
|
|
@@ -69590,13 +69588,8 @@ class Evaluator {
|
|
|
69590
69588
|
addDependencies(position, dependencies) {
|
|
69591
69589
|
this.formulaDependencies().addDependencies(position, dependencies);
|
|
69592
69590
|
for (const range of dependencies) {
|
|
69593
|
-
|
|
69594
|
-
|
|
69595
|
-
for (let col = left; col <= right; col++) {
|
|
69596
|
-
for (let row = top; row <= bottom; row++) {
|
|
69597
|
-
this.computeAndSave({ sheetId, col, row });
|
|
69598
|
-
}
|
|
69599
|
-
}
|
|
69591
|
+
// ensure that all ranges are computed
|
|
69592
|
+
this.compilationParams.ensureRange(range, false);
|
|
69600
69593
|
}
|
|
69601
69594
|
}
|
|
69602
69595
|
updateCompilationParameters() {
|
|
@@ -69824,6 +69817,10 @@ class Evaluator {
|
|
|
69824
69817
|
this.assertSheetHasEnoughSpaceToSpreadFormulaResult(formulaPosition, formulaReturn);
|
|
69825
69818
|
const nbColumns = formulaReturn.length;
|
|
69826
69819
|
const nbRows = formulaReturn[0].length;
|
|
69820
|
+
if (nbRows === 0) {
|
|
69821
|
+
// empty matrix
|
|
69822
|
+
return createEvaluatedCell({ value: 0 }, this.getters.getLocale(), cellData);
|
|
69823
|
+
}
|
|
69827
69824
|
const resultZone = {
|
|
69828
69825
|
top: formulaPosition.row,
|
|
69829
69826
|
bottom: formulaPosition.row + nbRows - 1,
|
|
@@ -70094,6 +70091,7 @@ class EvaluationPlugin extends CoreViewPlugin {
|
|
|
70094
70091
|
"getEvaluatedCellsPositions",
|
|
70095
70092
|
"getSpreadZone",
|
|
70096
70093
|
"getArrayFormulaSpreadingOn",
|
|
70094
|
+
"isArrayFormulaSpillBlocked",
|
|
70097
70095
|
"isEmpty",
|
|
70098
70096
|
];
|
|
70099
70097
|
shouldRebuildDependenciesGraph = true;
|
|
@@ -70213,6 +70211,9 @@ class EvaluationPlugin extends CoreViewPlugin {
|
|
|
70213
70211
|
getArrayFormulaSpreadingOn(position) {
|
|
70214
70212
|
return this.evaluator.getArrayFormulaSpreadingOn(position);
|
|
70215
70213
|
}
|
|
70214
|
+
isArrayFormulaSpillBlocked(position) {
|
|
70215
|
+
return this.evaluator.isArrayFormulaSpillBlocked(position);
|
|
70216
|
+
}
|
|
70216
70217
|
/**
|
|
70217
70218
|
* Check if a zone only contains empty cells
|
|
70218
70219
|
*/
|
|
@@ -74411,7 +74412,7 @@ class Session extends EventBus {
|
|
|
74411
74412
|
}
|
|
74412
74413
|
delete this.clients[this.clientId];
|
|
74413
74414
|
this.transportService.leave(this.clientId);
|
|
74414
|
-
this.
|
|
74415
|
+
this.sendToTransport({
|
|
74415
74416
|
type: "CLIENT_LEFT",
|
|
74416
74417
|
clientId: this.clientId,
|
|
74417
74418
|
version: MESSAGE_VERSION,
|
|
@@ -74425,7 +74426,7 @@ class Session extends EventBus {
|
|
|
74425
74426
|
return;
|
|
74426
74427
|
}
|
|
74427
74428
|
const snapshotId = this.uuidGenerator.uuidv4();
|
|
74428
|
-
await this.
|
|
74429
|
+
await this.sendToTransport({
|
|
74429
74430
|
type: "SNAPSHOT",
|
|
74430
74431
|
nextRevisionId: snapshotId,
|
|
74431
74432
|
serverRevisionId: this.serverRevisionId,
|
|
@@ -74473,10 +74474,14 @@ class Session extends EventBus {
|
|
|
74473
74474
|
const type = currentPosition ? "CLIENT_MOVED" : "CLIENT_JOINED";
|
|
74474
74475
|
const client = this.getCurrentClient();
|
|
74475
74476
|
this.clients[this.clientId] = { ...client, position };
|
|
74476
|
-
this.
|
|
74477
|
+
this.sendToTransport({
|
|
74477
74478
|
type,
|
|
74478
74479
|
version: MESSAGE_VERSION,
|
|
74479
74480
|
client: { ...client, position },
|
|
74481
|
+
}).then(() => {
|
|
74482
|
+
if (this.pendingMessages.length > 0 && !this.waitingAck) {
|
|
74483
|
+
this.sendPendingMessage();
|
|
74484
|
+
}
|
|
74480
74485
|
});
|
|
74481
74486
|
}
|
|
74482
74487
|
/**
|
|
@@ -74557,7 +74562,7 @@ class Session extends EventBus {
|
|
|
74557
74562
|
if (client) {
|
|
74558
74563
|
const { position } = client;
|
|
74559
74564
|
if (position) {
|
|
74560
|
-
this.
|
|
74565
|
+
this.sendToTransport({
|
|
74561
74566
|
type: "CLIENT_MOVED",
|
|
74562
74567
|
version: MESSAGE_VERSION,
|
|
74563
74568
|
client: { ...client, position },
|
|
@@ -74578,6 +74583,10 @@ class Session extends EventBus {
|
|
|
74578
74583
|
}
|
|
74579
74584
|
this.sendPendingMessage();
|
|
74580
74585
|
}
|
|
74586
|
+
async sendToTransport(message) {
|
|
74587
|
+
// wrap in an async function to ensure it returns a promise
|
|
74588
|
+
return this.transportService.sendMessage(message);
|
|
74589
|
+
}
|
|
74581
74590
|
/**
|
|
74582
74591
|
* Send the next pending message
|
|
74583
74592
|
*/
|
|
@@ -74606,9 +74615,14 @@ class Session extends EventBus {
|
|
|
74606
74615
|
${JSON.stringify(message)}`);
|
|
74607
74616
|
}
|
|
74608
74617
|
this.waitingAck = true;
|
|
74609
|
-
this.
|
|
74618
|
+
this.sendToTransport({
|
|
74610
74619
|
...message,
|
|
74611
74620
|
serverRevisionId: this.serverRevisionId,
|
|
74621
|
+
}).catch((e) => {
|
|
74622
|
+
if (!(e instanceof ClientDisconnectedError)) {
|
|
74623
|
+
throw e.cause || e;
|
|
74624
|
+
}
|
|
74625
|
+
this.waitingAck = false;
|
|
74612
74626
|
});
|
|
74613
74627
|
}
|
|
74614
74628
|
acknowledge(message) {
|
|
@@ -82114,10 +82128,8 @@ class SpreadsheetDashboard extends owl.Component {
|
|
|
82114
82128
|
});
|
|
82115
82129
|
}
|
|
82116
82130
|
get gridContainer() {
|
|
82117
|
-
const
|
|
82118
|
-
|
|
82119
|
-
const { end } = this.env.model.getters.getColDimensions(sheetId, right);
|
|
82120
|
-
return cssPropertiesToCss({ "max-width": `${end}px` });
|
|
82131
|
+
const maxWidth = this.getMaxSheetWidth();
|
|
82132
|
+
return cssPropertiesToCss({ "max-width": `${maxWidth}px` });
|
|
82121
82133
|
}
|
|
82122
82134
|
get gridOverlayDimensions() {
|
|
82123
82135
|
return cssPropertiesToCss({
|
|
@@ -82149,10 +82161,12 @@ class SpreadsheetDashboard extends owl.Component {
|
|
|
82149
82161
|
onClosePopover() {
|
|
82150
82162
|
this.cellPopovers.close();
|
|
82151
82163
|
}
|
|
82152
|
-
onGridResized(
|
|
82164
|
+
onGridResized() {
|
|
82165
|
+
const { height, width } = this.props.getGridSize();
|
|
82166
|
+
const maxWidth = this.getMaxSheetWidth();
|
|
82153
82167
|
this.env.model.dispatch("RESIZE_SHEETVIEW", {
|
|
82154
|
-
width: width,
|
|
82155
|
-
height
|
|
82168
|
+
width: Math.min(maxWidth, width),
|
|
82169
|
+
height,
|
|
82156
82170
|
gridOffsetX: 0,
|
|
82157
82171
|
gridOffsetY: 0,
|
|
82158
82172
|
});
|
|
@@ -82170,6 +82184,11 @@ class SpreadsheetDashboard extends owl.Component {
|
|
|
82170
82184
|
...this.env.model.getters.getSheetViewDimensionWithHeaders(),
|
|
82171
82185
|
};
|
|
82172
82186
|
}
|
|
82187
|
+
getMaxSheetWidth() {
|
|
82188
|
+
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
82189
|
+
const { right } = this.env.model.getters.getSheetZone(sheetId);
|
|
82190
|
+
return this.env.model.getters.getColDimensions(sheetId, right).end;
|
|
82191
|
+
}
|
|
82173
82192
|
}
|
|
82174
82193
|
|
|
82175
82194
|
css /* scss */ `
|
|
@@ -84318,7 +84337,7 @@ class Spreadsheet extends owl.Component {
|
|
|
84318
84337
|
document.activeElement?.contains(this.spreadsheetRef.el)) {
|
|
84319
84338
|
this.focusGrid();
|
|
84320
84339
|
}
|
|
84321
|
-
}
|
|
84340
|
+
});
|
|
84322
84341
|
owl.useExternalListener(window, "resize", () => this.render(true));
|
|
84323
84342
|
// For some reason, the wheel event is not properly registered inside templates
|
|
84324
84343
|
// in Chromium-based browsers based on chromium 125
|
|
@@ -84411,22 +84430,20 @@ class Spreadsheet extends owl.Component {
|
|
|
84411
84430
|
return this.env.model.getters.getVisibleGroupLayers(sheetId, "COL");
|
|
84412
84431
|
}
|
|
84413
84432
|
getGridSize() {
|
|
84414
|
-
const
|
|
84415
|
-
|
|
84416
|
-
|
|
84417
|
-
|
|
84418
|
-
|
|
84419
|
-
|
|
84420
|
-
const
|
|
84421
|
-
const
|
|
84422
|
-
|
|
84423
|
-
|
|
84424
|
-
|
|
84425
|
-
|
|
84426
|
-
|
|
84427
|
-
|
|
84428
|
-
height: Math.max(gridHeight - SCROLLBAR_WIDTH, 0),
|
|
84429
|
-
};
|
|
84433
|
+
const el = this.spreadsheetRef.el;
|
|
84434
|
+
if (!el) {
|
|
84435
|
+
return { width: 0, height: 0 };
|
|
84436
|
+
}
|
|
84437
|
+
const getHeight = (selector) => el.querySelector(selector)?.getBoundingClientRect().height || 0;
|
|
84438
|
+
const getWidth = (selector) => el.querySelector(selector)?.getBoundingClientRect().width || 0;
|
|
84439
|
+
const rect = el.getBoundingClientRect();
|
|
84440
|
+
const topBarHeight = getHeight(".o-spreadsheet-topbar-wrapper");
|
|
84441
|
+
const bottomBarHeight = getHeight(".o-spreadsheet-bottombar-wrapper");
|
|
84442
|
+
const colGroupHeight = getHeight(".o-column-groups");
|
|
84443
|
+
const gridWidth = getWidth(".o-grid");
|
|
84444
|
+
const width = Math.max(gridWidth - SCROLLBAR_WIDTH, 0);
|
|
84445
|
+
const height = Math.max(rect.height - topBarHeight - bottomBarHeight - colGroupHeight - SCROLLBAR_WIDTH, 0);
|
|
84446
|
+
return { width, height };
|
|
84430
84447
|
}
|
|
84431
84448
|
}
|
|
84432
84449
|
|
|
@@ -84439,7 +84456,7 @@ class ReadonlyTransportFilter {
|
|
|
84439
84456
|
if (message.type === "CLIENT_JOINED" ||
|
|
84440
84457
|
message.type === "CLIENT_LEFT" ||
|
|
84441
84458
|
message.type === "CLIENT_MOVED") {
|
|
84442
|
-
this.transportService.sendMessage(message);
|
|
84459
|
+
await this.transportService.sendMessage(message);
|
|
84443
84460
|
}
|
|
84444
84461
|
// ignore all other messages
|
|
84445
84462
|
}
|
|
@@ -89108,6 +89125,6 @@ exports.tokenColors = tokenColors;
|
|
|
89108
89125
|
exports.tokenize = tokenize;
|
|
89109
89126
|
|
|
89110
89127
|
|
|
89111
|
-
__info__.version = "19.0.
|
|
89112
|
-
__info__.date = "
|
|
89113
|
-
__info__.hash = "
|
|
89128
|
+
__info__.version = "19.0.16";
|
|
89129
|
+
__info__.date = "2026-01-07T16:21:15.857Z";
|
|
89130
|
+
__info__.hash = "9f3f13a";
|