@odoo/o-spreadsheet 18.5.0-alpha.0 → 18.5.0-alpha.2
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 +244 -76
- package/dist/o-spreadsheet.d.ts +40 -2
- package/dist/o-spreadsheet.esm.js +244 -76
- package/dist/o-spreadsheet.iife.js +244 -76
- package/dist/o-spreadsheet.iife.min.js +391 -391
- package/dist/o_spreadsheet.xml +29 -27
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 18.5.0-alpha.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.5.0-alpha.2
|
|
6
|
+
* @date 2025-07-11T11:13:53.317Z
|
|
7
|
+
* @hash 6d42178
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -854,6 +854,7 @@ const specialWhiteSpaceSpecialCharacters = [
|
|
|
854
854
|
];
|
|
855
855
|
const specialWhiteSpaceRegexp = new RegExp(specialWhiteSpaceSpecialCharacters.join("|"), "g");
|
|
856
856
|
const newLineRegexp = /(\r\n|\r)/g;
|
|
857
|
+
const whiteSpaceCharacters = specialWhiteSpaceSpecialCharacters.concat([" "]);
|
|
857
858
|
/**
|
|
858
859
|
* Replace all different newlines characters by \n
|
|
859
860
|
*/
|
|
@@ -1990,8 +1991,9 @@ const INITIAL_JS_DAY = DateTime.fromTimestamp(0);
|
|
|
1990
1991
|
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY.getTime() - INITIAL_1900_DAY.getTime();
|
|
1991
1992
|
const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
|
|
1992
1993
|
const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
|
|
1993
|
-
const
|
|
1994
|
-
const
|
|
1994
|
+
const whiteSpaceChars = whiteSpaceCharacters.join("");
|
|
1995
|
+
const dateSeparatorsRegex = new RegExp(`\/|-|${whiteSpaceCharacters.join("|")}`);
|
|
1996
|
+
const dateRegexp = new RegExp(`^(\\d{1,4})[\/${whiteSpaceChars}\-](\\d{1,4})([\/${whiteSpaceChars}\-](\\d{1,4}))?$`);
|
|
1995
1997
|
const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
|
|
1996
1998
|
/** Convert a value number representing a date, or return undefined if it isn't possible */
|
|
1997
1999
|
function valueToDateNumber(value, locale) {
|
|
@@ -6926,6 +6928,8 @@ function splitWordToSpecificWidth(ctx, word, width, style) {
|
|
|
6926
6928
|
function splitTextToWidth(ctx, text, style, width) {
|
|
6927
6929
|
if (!style)
|
|
6928
6930
|
style = {};
|
|
6931
|
+
if (isMarkdownLink(text))
|
|
6932
|
+
text = parseMarkdownLink(text).label;
|
|
6929
6933
|
const brokenText = [];
|
|
6930
6934
|
// Checking if text contains NEWLINE before split makes it very slightly slower if text contains it,
|
|
6931
6935
|
// but 5-10x faster if it doesn't
|
|
@@ -8766,6 +8770,10 @@ function toNormalizedPivotValue(dimension, groupValue) {
|
|
|
8766
8770
|
if (groupValue === null || groupValue === "null") {
|
|
8767
8771
|
return null;
|
|
8768
8772
|
}
|
|
8773
|
+
const extractedGroupValue = typeof groupValue === "object" ? groupValue.value : groupValue;
|
|
8774
|
+
if (isEvaluationError(extractedGroupValue)) {
|
|
8775
|
+
return extractedGroupValue;
|
|
8776
|
+
}
|
|
8769
8777
|
const groupValueString = typeof groupValue === "boolean"
|
|
8770
8778
|
? toString(groupValue).toLocaleLowerCase()
|
|
8771
8779
|
: toString(groupValue);
|
|
@@ -26510,6 +26518,51 @@ cellAnimationRegistry.add("textFadeOut", {
|
|
|
26510
26518
|
Object.assign(animatedBox.style, style);
|
|
26511
26519
|
},
|
|
26512
26520
|
});
|
|
26521
|
+
cellAnimationRegistry.add("iconFadeIn", {
|
|
26522
|
+
id: "iconFadeIn",
|
|
26523
|
+
easingFn: "easeInCubic",
|
|
26524
|
+
hasAnimation: (oldBox, newBox) => {
|
|
26525
|
+
return Boolean((!oldBox?.icons?.left && newBox?.icons?.left) ||
|
|
26526
|
+
(!oldBox?.icons?.right && newBox?.icons?.right) ||
|
|
26527
|
+
(!oldBox?.icons?.center && newBox?.icons?.center));
|
|
26528
|
+
},
|
|
26529
|
+
updateAnimation: function (progress, animatedBox, oldBox, newBox) {
|
|
26530
|
+
const iconOpacity = EASING_FN[this.easingFn](progress);
|
|
26531
|
+
if (animatedBox.icons.left && newBox.icons.left && !oldBox.icons.left) {
|
|
26532
|
+
animatedBox.icons.left.opacity = iconOpacity;
|
|
26533
|
+
}
|
|
26534
|
+
if (animatedBox.icons.right && newBox.icons.right && !oldBox.icons.right) {
|
|
26535
|
+
animatedBox.icons.right.opacity = iconOpacity;
|
|
26536
|
+
}
|
|
26537
|
+
if (animatedBox.icons.center && newBox.icons.center && !oldBox.icons.center) {
|
|
26538
|
+
animatedBox.icons.center.opacity = iconOpacity;
|
|
26539
|
+
}
|
|
26540
|
+
},
|
|
26541
|
+
});
|
|
26542
|
+
cellAnimationRegistry.add("iconFadeOut", {
|
|
26543
|
+
id: "iconFadeOut",
|
|
26544
|
+
easingFn: "easeOutCubic",
|
|
26545
|
+
hasAnimation: (oldBox, newBox) => {
|
|
26546
|
+
return Boolean((oldBox?.icons?.left && !newBox?.icons?.left) ||
|
|
26547
|
+
(oldBox?.icons?.right && !newBox?.icons?.right) ||
|
|
26548
|
+
(oldBox?.icons?.center && !newBox?.icons?.center));
|
|
26549
|
+
},
|
|
26550
|
+
updateAnimation: function (progress, animatedBox, oldBox, newBox) {
|
|
26551
|
+
const iconOpacity = 1 - EASING_FN[this.easingFn](progress);
|
|
26552
|
+
if (!animatedBox.icons) {
|
|
26553
|
+
animatedBox.icons = {};
|
|
26554
|
+
}
|
|
26555
|
+
if (oldBox.icons.left && !newBox.icons.left) {
|
|
26556
|
+
animatedBox.icons.left = { ...oldBox.icons.left, opacity: iconOpacity };
|
|
26557
|
+
}
|
|
26558
|
+
if (oldBox.icons.right && !newBox.icons.right) {
|
|
26559
|
+
animatedBox.icons.right = { ...oldBox.icons.right, opacity: iconOpacity };
|
|
26560
|
+
}
|
|
26561
|
+
if (oldBox.icons.center && !newBox.icons.center) {
|
|
26562
|
+
animatedBox.icons.center = { ...oldBox.icons.center, opacity: iconOpacity };
|
|
26563
|
+
}
|
|
26564
|
+
},
|
|
26565
|
+
});
|
|
26513
26566
|
cellAnimationRegistry.add("textChange", {
|
|
26514
26567
|
id: "textChange",
|
|
26515
26568
|
easingFn: "easeOutCubic",
|
|
@@ -26518,7 +26571,7 @@ cellAnimationRegistry.add("textChange", {
|
|
|
26518
26571
|
const newText = newBox?.content?.textLines?.join("\n");
|
|
26519
26572
|
// Note: here, we also animate changes to icons layout (margins/size change, or icon appearing/disappearing)
|
|
26520
26573
|
// because a change to the icon layout will impact where the text is positioned.
|
|
26521
|
-
return
|
|
26574
|
+
return Boolean(oldText && newText && (oldText !== newText || hasIconLayoutChange(newBox, oldBox)));
|
|
26522
26575
|
},
|
|
26523
26576
|
updateAnimation: function (progress, animatedBox, oldBox, newBox) {
|
|
26524
26577
|
const value = EASING_FN[this.easingFn](progress);
|
|
@@ -26533,7 +26586,7 @@ cellAnimationRegistry.add("textChange", {
|
|
|
26533
26586
|
height: newBox.height,
|
|
26534
26587
|
style: { ...newBox.style },
|
|
26535
26588
|
skipCellGridLines: true,
|
|
26536
|
-
content: newBox.content,
|
|
26589
|
+
content: newBox.content ? { ...newBox.content } : undefined,
|
|
26537
26590
|
clipRect: newBox.clipRect || {
|
|
26538
26591
|
...newBox,
|
|
26539
26592
|
// large width to avoid clipping the text it it didn't have a clipRect before,
|
|
@@ -26553,7 +26606,7 @@ cellAnimationRegistry.add("textChange", {
|
|
|
26553
26606
|
height: newBox.height,
|
|
26554
26607
|
style: { ...oldBox.style },
|
|
26555
26608
|
skipCellGridLines: true,
|
|
26556
|
-
content: oldBox.content,
|
|
26609
|
+
content: oldBox.content ? { ...oldBox.content } : undefined,
|
|
26557
26610
|
clipRect: oldBox.clipRect || {
|
|
26558
26611
|
...newBox,
|
|
26559
26612
|
x: Math.max(0, newBox.x - (oldBox.content?.width || 0)),
|
|
@@ -27403,7 +27456,9 @@ function getSectionThresholdValue(sheetId, threshold, minValue, maxValue, getter
|
|
|
27403
27456
|
}
|
|
27404
27457
|
function getFormulaNumberValue(sheetId, formula, getters) {
|
|
27405
27458
|
const value = getters.evaluateFormula(sheetId, formula);
|
|
27406
|
-
return
|
|
27459
|
+
return isMultipleElementMatrix(value)
|
|
27460
|
+
? undefined
|
|
27461
|
+
: tryToNumber(toScalar(value), getters.getLocale());
|
|
27407
27462
|
}
|
|
27408
27463
|
function getInvalidGaugeRuntime(chart, getters) {
|
|
27409
27464
|
return {
|
|
@@ -31028,6 +31083,9 @@ class ErrorToolTip extends owl.Component {
|
|
|
31028
31083
|
return undefined;
|
|
31029
31084
|
}
|
|
31030
31085
|
get errorOriginPositionString() {
|
|
31086
|
+
if (this.env.model.getters.isDashboard()) {
|
|
31087
|
+
return "";
|
|
31088
|
+
}
|
|
31031
31089
|
const evaluationError = this.evaluationError;
|
|
31032
31090
|
const position = evaluationError?.errorOriginPosition;
|
|
31033
31091
|
if (!position || deepEquals(position, this.props.cellPosition)) {
|
|
@@ -32665,7 +32723,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
32665
32723
|
}
|
|
32666
32724
|
captureSelection(zone, col, row) {
|
|
32667
32725
|
this.model.selection.capture(this, {
|
|
32668
|
-
cell: { col: col
|
|
32726
|
+
cell: { col: col ?? zone.left, row: row ?? zone.right },
|
|
32669
32727
|
zone,
|
|
32670
32728
|
}, {
|
|
32671
32729
|
handleEvent: this.handleEvent.bind(this),
|
|
@@ -39176,40 +39234,112 @@ function convertPivotTableConfig(pivotTable) {
|
|
|
39176
39234
|
* In all the sheets, replace the table-only references in the formula cells with standard references.
|
|
39177
39235
|
*/
|
|
39178
39236
|
function convertTableFormulaReferences(convertedSheets, xlsxSheets) {
|
|
39237
|
+
let deconstructedSheets = null;
|
|
39179
39238
|
for (const tableSheet of convertedSheets) {
|
|
39180
39239
|
const tables = xlsxSheets.find((s) => isSheetNameEqual(s.sheetName, tableSheet.name)).tables;
|
|
39240
|
+
if (!tables || tables.length === 0) {
|
|
39241
|
+
continue;
|
|
39242
|
+
}
|
|
39243
|
+
// Only deconstruct sheets if we are sure there are tables to process
|
|
39244
|
+
if (!deconstructedSheets) {
|
|
39245
|
+
deconstructedSheets = deconstructSheets(convertedSheets);
|
|
39246
|
+
}
|
|
39181
39247
|
for (const table of tables) {
|
|
39182
|
-
const
|
|
39183
|
-
|
|
39184
|
-
for (const xc in
|
|
39185
|
-
const
|
|
39186
|
-
let
|
|
39187
|
-
|
|
39188
|
-
|
|
39189
|
-
|
|
39190
|
-
let endIndex = refIndex + tabRef.length;
|
|
39191
|
-
let openBrackets = 1;
|
|
39192
|
-
while (openBrackets > 0 && endIndex < cellContent.length) {
|
|
39193
|
-
if (cellContent[endIndex] === "[") {
|
|
39194
|
-
openBrackets++;
|
|
39195
|
-
}
|
|
39196
|
-
else if (cellContent[endIndex] === "]") {
|
|
39197
|
-
openBrackets--;
|
|
39198
|
-
}
|
|
39199
|
-
endIndex++;
|
|
39200
|
-
}
|
|
39201
|
-
const reference = cellContent.slice(refIndex + tabRef.length, endIndex - 1);
|
|
39202
|
-
const sheetPrefix = tableSheet.id === sheet.id ? "" : tableSheet.name + "!";
|
|
39203
|
-
const convertedRef = convertTableReference(sheetPrefix, reference, table, xc);
|
|
39204
|
-
cellContent =
|
|
39205
|
-
cellContent.slice(0, refIndex) + convertedRef + cellContent.slice(endIndex);
|
|
39248
|
+
for (const sheetId in deconstructedSheets) {
|
|
39249
|
+
const sheet = convertedSheets.find((s) => s.id === sheetId);
|
|
39250
|
+
for (const xc in deconstructedSheets[sheetId]) {
|
|
39251
|
+
const deconstructedCell = deconstructedSheets[sheetId][xc];
|
|
39252
|
+
for (let i = deconstructedCell.length - 3; i >= 0; i -= 2) {
|
|
39253
|
+
const possibleTable = deconstructedSheets[sheetId][xc][i];
|
|
39254
|
+
if (!possibleTable.endsWith(table.name)) {
|
|
39255
|
+
continue;
|
|
39206
39256
|
}
|
|
39257
|
+
const possibleRef = deconstructedSheets[sheetId][xc][i + 1];
|
|
39258
|
+
const sheetPrefix = tableSheet.id === sheet.id ? "" : tableSheet.name + "!";
|
|
39259
|
+
const convertedRef = convertTableReference(sheetPrefix, possibleRef, table, xc);
|
|
39260
|
+
deconstructedSheets[sheetId][xc][i + 2] =
|
|
39261
|
+
possibleTable.slice(0, possibleTable.indexOf(table.name)) +
|
|
39262
|
+
convertedRef +
|
|
39263
|
+
deconstructedSheets[sheetId][xc][i + 2];
|
|
39264
|
+
deconstructedSheets[sheetId][xc].splice(i, 2);
|
|
39207
39265
|
}
|
|
39208
|
-
sheet.cells[xc] = cellContent;
|
|
39266
|
+
// sheet.cells[xc] = cellContent;
|
|
39209
39267
|
}
|
|
39210
39268
|
}
|
|
39211
39269
|
}
|
|
39212
39270
|
}
|
|
39271
|
+
if (!deconstructedSheets) {
|
|
39272
|
+
return;
|
|
39273
|
+
}
|
|
39274
|
+
for (const sheetId in deconstructedSheets) {
|
|
39275
|
+
const sheet = convertedSheets.find((s) => s.id === sheetId);
|
|
39276
|
+
for (const xc in deconstructedSheets[sheetId]) {
|
|
39277
|
+
const deconstructedCell = deconstructedSheets[sheetId][xc];
|
|
39278
|
+
if (deconstructedCell.length === 1) {
|
|
39279
|
+
sheet.cells[xc] = deconstructedCell[0];
|
|
39280
|
+
continue;
|
|
39281
|
+
}
|
|
39282
|
+
let newContent = "";
|
|
39283
|
+
for (let i = 0; i < deconstructedCell.length; i += 2) {
|
|
39284
|
+
newContent += deconstructedCell[i] + "[" + deconstructedCell[i + 1] + "]";
|
|
39285
|
+
}
|
|
39286
|
+
newContent += deconstructedCell[deconstructedCell.length - 1];
|
|
39287
|
+
sheet.cells[xc] = newContent;
|
|
39288
|
+
}
|
|
39289
|
+
}
|
|
39290
|
+
}
|
|
39291
|
+
/**
|
|
39292
|
+
* Deconstruct the content of the cells in the sheets to extract possible table references.
|
|
39293
|
+
* Example from "=AVERAGE(Table1[colName1])-AVERAGE(Table2[colName2])":
|
|
39294
|
+
* return --> ["=AVERAGE(Table1", "colName1", ")-AVERAGE(Table2", "colName2", ")"]
|
|
39295
|
+
*/
|
|
39296
|
+
function deconstructSheets(convertedSheets) {
|
|
39297
|
+
const deconstructedSheets = {};
|
|
39298
|
+
for (const sheet of convertedSheets) {
|
|
39299
|
+
for (const xc in sheet.cells) {
|
|
39300
|
+
const cellContent = sheet.cells[xc];
|
|
39301
|
+
if (!cellContent || !cellContent.startsWith("=")) {
|
|
39302
|
+
continue;
|
|
39303
|
+
}
|
|
39304
|
+
const startIndex = cellContent.indexOf("[");
|
|
39305
|
+
if (startIndex === -1) {
|
|
39306
|
+
continue;
|
|
39307
|
+
}
|
|
39308
|
+
const deconstructedCell = [];
|
|
39309
|
+
let possibleTable = cellContent.slice(0, startIndex);
|
|
39310
|
+
let possibleRef = "";
|
|
39311
|
+
let openBrackets = 1;
|
|
39312
|
+
let mainPossibleTableIndex = 0;
|
|
39313
|
+
let mainOpenBracketIndex = startIndex;
|
|
39314
|
+
for (let index = startIndex + 1; index < cellContent.length; index++) {
|
|
39315
|
+
if (cellContent[index] === "[") {
|
|
39316
|
+
if (openBrackets === 0) {
|
|
39317
|
+
possibleTable = cellContent.slice(mainPossibleTableIndex, index);
|
|
39318
|
+
mainOpenBracketIndex = index;
|
|
39319
|
+
}
|
|
39320
|
+
openBrackets++;
|
|
39321
|
+
continue;
|
|
39322
|
+
}
|
|
39323
|
+
if (cellContent[index] === "]") {
|
|
39324
|
+
openBrackets--;
|
|
39325
|
+
if (openBrackets === 0) {
|
|
39326
|
+
possibleRef = cellContent.slice(mainOpenBracketIndex + 1, index);
|
|
39327
|
+
deconstructedCell.push(possibleTable);
|
|
39328
|
+
deconstructedCell.push(possibleRef);
|
|
39329
|
+
mainPossibleTableIndex = index + 1;
|
|
39330
|
+
}
|
|
39331
|
+
}
|
|
39332
|
+
}
|
|
39333
|
+
if (deconstructedCell.length) {
|
|
39334
|
+
if (!deconstructedSheets[sheet.id]) {
|
|
39335
|
+
deconstructedSheets[sheet.id] = {};
|
|
39336
|
+
}
|
|
39337
|
+
deconstructedCell.push(cellContent.slice(mainPossibleTableIndex));
|
|
39338
|
+
deconstructedSheets[sheet.id][xc] = [...deconstructedCell];
|
|
39339
|
+
}
|
|
39340
|
+
}
|
|
39341
|
+
}
|
|
39342
|
+
return deconstructedSheets;
|
|
39213
39343
|
}
|
|
39214
39344
|
/**
|
|
39215
39345
|
* Convert table-specific references in formulas into standard references. A table reference is composed of columns names,
|
|
@@ -45521,10 +45651,10 @@ class CellComposerStore extends AbstractComposerStore {
|
|
|
45521
45651
|
const cellValue = isFormula(content)
|
|
45522
45652
|
? this.getters.evaluateFormula(this.sheetId, content)
|
|
45523
45653
|
: parseLiteral(content, this.getters.getLocale());
|
|
45524
|
-
if (
|
|
45654
|
+
if (isMultipleElementMatrix(cellValue)) {
|
|
45525
45655
|
return true;
|
|
45526
45656
|
}
|
|
45527
|
-
const validationResult = this.getters.getValidationResultForCellValue(cellValue, cellPosition);
|
|
45657
|
+
const validationResult = this.getters.getValidationResultForCellValue(toScalar(cellValue), cellPosition);
|
|
45528
45658
|
if (!validationResult.isValid && validationResult.rule.isBlocking) {
|
|
45529
45659
|
return false;
|
|
45530
45660
|
}
|
|
@@ -47945,6 +48075,7 @@ class GridRenderer extends SpreadsheetStore {
|
|
|
47945
48075
|
continue;
|
|
47946
48076
|
}
|
|
47947
48077
|
ctx.save();
|
|
48078
|
+
ctx.globalAlpha = icon.opacity ?? 1;
|
|
47948
48079
|
ctx.beginPath();
|
|
47949
48080
|
const clipRect = icon.clipRect || box;
|
|
47950
48081
|
ctx.rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
|
|
@@ -50635,10 +50766,10 @@ class GaugeChartDesignPanel extends owl.Component {
|
|
|
50635
50766
|
return tryToNumber(value, locale) !== undefined;
|
|
50636
50767
|
}
|
|
50637
50768
|
const evaluatedValue = this.env.model.getters.evaluateFormula(this.sheetId, value);
|
|
50638
|
-
if (
|
|
50769
|
+
if (isMultipleElementMatrix(evaluatedValue)) {
|
|
50639
50770
|
return false;
|
|
50640
50771
|
}
|
|
50641
|
-
return tryToNumber(evaluatedValue, locale) !== undefined;
|
|
50772
|
+
return tryToNumber(toScalar(evaluatedValue), locale) !== undefined;
|
|
50642
50773
|
}
|
|
50643
50774
|
get sheetId() {
|
|
50644
50775
|
const chart = this.env.model.getters.getChart(this.props.figureId);
|
|
@@ -51492,12 +51623,32 @@ class ChartPanel extends owl.Component {
|
|
|
51492
51623
|
static template = "o-spreadsheet-ChartPanel";
|
|
51493
51624
|
static components = { Section, ChartTypePicker };
|
|
51494
51625
|
static props = { onCloseSidePanel: Function, figureId: String };
|
|
51626
|
+
panelContentRef;
|
|
51627
|
+
scrollPositions = {
|
|
51628
|
+
configuration: 0,
|
|
51629
|
+
design: 0,
|
|
51630
|
+
};
|
|
51495
51631
|
store;
|
|
51496
51632
|
get figureId() {
|
|
51497
51633
|
return this.props.figureId;
|
|
51498
51634
|
}
|
|
51499
51635
|
setup() {
|
|
51500
51636
|
this.store = useLocalStore(MainChartPanelStore);
|
|
51637
|
+
this.panelContentRef = owl.useRef("panelContent");
|
|
51638
|
+
owl.useEffect(() => {
|
|
51639
|
+
const el = this.panelContentRef.el;
|
|
51640
|
+
const activePanel = this.store.panel;
|
|
51641
|
+
if (el) {
|
|
51642
|
+
el.scrollTop = this.scrollPositions[activePanel];
|
|
51643
|
+
}
|
|
51644
|
+
}, () => [this.store.panel]);
|
|
51645
|
+
}
|
|
51646
|
+
switchPanel(panel) {
|
|
51647
|
+
const el = this.panelContentRef.el;
|
|
51648
|
+
if (el) {
|
|
51649
|
+
this.scrollPositions[this.store.panel] = el.scrollTop;
|
|
51650
|
+
}
|
|
51651
|
+
this.store.activatePanel(panel);
|
|
51501
51652
|
}
|
|
51502
51653
|
updateChart(figureId, updateDefinition) {
|
|
51503
51654
|
if (figureId !== this.figureId) {
|
|
@@ -52333,6 +52484,9 @@ class ConditionalFormattingPanel extends owl.Component {
|
|
|
52333
52484
|
this.switchToList();
|
|
52334
52485
|
}
|
|
52335
52486
|
}
|
|
52487
|
+
else if (!this.editedCF) {
|
|
52488
|
+
this.switchToList();
|
|
52489
|
+
}
|
|
52336
52490
|
});
|
|
52337
52491
|
}
|
|
52338
52492
|
get conditionalFormats() {
|
|
@@ -55446,10 +55600,7 @@ class SpreadsheetPivot {
|
|
|
55446
55600
|
if (finalCell.value === null) {
|
|
55447
55601
|
return { value: _t("(Undefined)") };
|
|
55448
55602
|
}
|
|
55449
|
-
return
|
|
55450
|
-
value: finalCell.value,
|
|
55451
|
-
format: finalCell.format,
|
|
55452
|
-
};
|
|
55603
|
+
return finalCell;
|
|
55453
55604
|
}
|
|
55454
55605
|
getPivotCellValueAndFormat(measureId, domain) {
|
|
55455
55606
|
const dataEntries = this.filterDataEntriesFromDomain(this.dataEntries, domain);
|
|
@@ -55687,7 +55838,6 @@ pivotRegistry.add("SPREADSHEET", {
|
|
|
55687
55838
|
ui: SpreadsheetPivot,
|
|
55688
55839
|
definition: SpreadsheetPivotRuntimeDefinition,
|
|
55689
55840
|
externalData: false,
|
|
55690
|
-
onIterationEndEvaluation: (pivot) => pivot.markAsDirtyForEvaluation(),
|
|
55691
55841
|
dateGranularities: [...dateGranularities],
|
|
55692
55842
|
datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
|
|
55693
55843
|
isMeasureCandidate: (field) => field.type !== "boolean",
|
|
@@ -64338,7 +64488,7 @@ const onIterationEndEvaluationRegistry = new Registry();
|
|
|
64338
64488
|
onIterationEndEvaluationRegistry.add("pivots", (getters) => {
|
|
64339
64489
|
for (const pivotId of getters.getPivotIds()) {
|
|
64340
64490
|
const pivot = getters.getPivot(pivotId);
|
|
64341
|
-
|
|
64491
|
+
pivot.markAsDirtyForEvaluation?.();
|
|
64342
64492
|
}
|
|
64343
64493
|
});
|
|
64344
64494
|
|
|
@@ -66802,12 +66952,12 @@ class EvaluationConditionalFormatPlugin extends CoreViewPlugin {
|
|
|
66802
66952
|
}
|
|
66803
66953
|
return this.getters.evaluateFormula(sheetId, value) ?? "";
|
|
66804
66954
|
});
|
|
66805
|
-
if (evaluatedCriterionValues.some(
|
|
66955
|
+
if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
|
|
66806
66956
|
return false;
|
|
66807
66957
|
}
|
|
66808
66958
|
const evaluatedCriterion = {
|
|
66809
66959
|
type: rule.operator,
|
|
66810
|
-
values: evaluatedCriterionValues,
|
|
66960
|
+
values: evaluatedCriterionValues.map(toScalar),
|
|
66811
66961
|
};
|
|
66812
66962
|
return evaluator.isValueValid(cell.value ?? "", evaluatedCriterion, this.getters, sheetId);
|
|
66813
66963
|
}
|
|
@@ -66967,10 +67117,10 @@ class EvaluationDataValidationPlugin extends CoreViewPlugin {
|
|
|
66967
67117
|
const evaluator = criterionEvaluatorRegistry.get(criterion.type);
|
|
66968
67118
|
const offset = this.getCellOffsetInRule(cellPosition, rule);
|
|
66969
67119
|
const evaluatedCriterionValues = this.getEvaluatedCriterionValues(sheetId, offset, criterion);
|
|
66970
|
-
if (evaluatedCriterionValues.some(
|
|
67120
|
+
if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
|
|
66971
67121
|
return undefined;
|
|
66972
67122
|
}
|
|
66973
|
-
const evaluatedCriterion = { ...criterion, values: evaluatedCriterionValues };
|
|
67123
|
+
const evaluatedCriterion = { ...criterion, values: evaluatedCriterionValues.map(toScalar) };
|
|
66974
67124
|
if (evaluator.isValueValid(cellValue, evaluatedCriterion, this.getters, sheetId)) {
|
|
66975
67125
|
return undefined;
|
|
66976
67126
|
}
|
|
@@ -67613,13 +67763,13 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
67613
67763
|
super(custom, params);
|
|
67614
67764
|
this.getters = params.getters;
|
|
67615
67765
|
}
|
|
67616
|
-
|
|
67766
|
+
markAsDirtyForEvaluation() {
|
|
67617
67767
|
this.cache = {};
|
|
67618
67768
|
this.rankAsc = {};
|
|
67619
67769
|
this.rankDesc = {};
|
|
67620
67770
|
this.runningTotal = {};
|
|
67621
67771
|
this.runningTotalInPercent = {};
|
|
67622
|
-
super.
|
|
67772
|
+
super.markAsDirtyForEvaluation?.();
|
|
67623
67773
|
}
|
|
67624
67774
|
getPivotCellValueAndFormat(measureName, domain) {
|
|
67625
67775
|
return this.getMeasureDisplayValue(measureName, domain);
|
|
@@ -67744,7 +67894,7 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
67744
67894
|
return this.getSubTreeMatchingDomain(node.children, domain, domainLevel + 1);
|
|
67745
67895
|
}
|
|
67746
67896
|
}
|
|
67747
|
-
return
|
|
67897
|
+
return [];
|
|
67748
67898
|
}
|
|
67749
67899
|
treeToLeafDomains(tree, parentDomain = []) {
|
|
67750
67900
|
const domains = [];
|
|
@@ -68432,9 +68582,9 @@ autofillModifiersRegistry
|
|
|
68432
68582
|
.add("ALPHANUMERIC_INCREMENT_MODIFIER", {
|
|
68433
68583
|
apply: (rule, data) => {
|
|
68434
68584
|
rule.current += rule.increment;
|
|
68435
|
-
|
|
68436
|
-
|
|
68437
|
-
|
|
68585
|
+
let value = Math.abs(rule.current).toString();
|
|
68586
|
+
value = "0".repeat(Math.max(rule.numberPostfixLength - value.length, 0)) + value;
|
|
68587
|
+
const content = `${rule.prefix}${value}`;
|
|
68438
68588
|
return {
|
|
68439
68589
|
cellData: {
|
|
68440
68590
|
border: data.border,
|
|
@@ -68552,6 +68702,7 @@ const autofillRulesRegistry = new Registry();
|
|
|
68552
68702
|
const numberPostfixRegExp = /(\d+)$/;
|
|
68553
68703
|
const stringPrefixRegExp = /^(.*\D+)/;
|
|
68554
68704
|
const alphaNumericValueRegExp = /^(.*\D+)(\d+)$/;
|
|
68705
|
+
const leadingZerosRegex = /^0*/;
|
|
68555
68706
|
/**
|
|
68556
68707
|
* Get the consecutive evaluated cells that can pass the filter function (e.g. certain type filter).
|
|
68557
68708
|
* Return the one which contains the given cell
|
|
@@ -68683,12 +68834,18 @@ autofillRulesRegistry
|
|
|
68683
68834
|
generateRule: (cell, cells, direction) => {
|
|
68684
68835
|
const numberPostfix = parseInt(cell.content.match(numberPostfixRegExp)[0]);
|
|
68685
68836
|
const prefix = cell.content.match(stringPrefixRegExp)[0];
|
|
68686
|
-
const numberPostfixLength = cell.content.length - prefix.length;
|
|
68687
68837
|
const group = getGroup(cell, cells, (evaluatedCell) => evaluatedCell.type === CellValueType.text &&
|
|
68688
|
-
alphaNumericValueRegExp.test(evaluatedCell.value))
|
|
68838
|
+
alphaNumericValueRegExp.test(evaluatedCell.value))
|
|
68839
|
+
// get consecutive alphanumeric cells, no matter what the prefix is
|
|
68689
68840
|
.filter((cell) => prefix === (cell.value ?? "").toString().match(stringPrefixRegExp)[0])
|
|
68690
|
-
.map((cell) =>
|
|
68691
|
-
|
|
68841
|
+
.map((cell) => (cell.value ?? "").toString().match(numberPostfixRegExp)[0]);
|
|
68842
|
+
// find the length of number with the most leading zeros
|
|
68843
|
+
const mostLeadingZeros = group.reduce((candidate, current) => {
|
|
68844
|
+
const currentLength = current.match(leadingZerosRegex)[0].length;
|
|
68845
|
+
return currentLength > candidate[1] ? [current, currentLength] : candidate;
|
|
68846
|
+
}, [group[0], 0]);
|
|
68847
|
+
const numberPostfixLength = mostLeadingZeros[1] ? mostLeadingZeros[0].length : 0;
|
|
68848
|
+
let increment = calculateIncrementBasedOnGroup(group.map((x) => parseInt(x)));
|
|
68692
68849
|
if (["up", "left"].includes(direction) && group.length === 1) {
|
|
68693
68850
|
increment = -increment;
|
|
68694
68851
|
}
|
|
@@ -73476,12 +73633,12 @@ class FilterEvaluationPlugin extends UIPlugin {
|
|
|
73476
73633
|
}
|
|
73477
73634
|
return this.getters.evaluateFormula(sheetId, value) ?? "";
|
|
73478
73635
|
});
|
|
73479
|
-
if (evaluatedCriterionValues.some(
|
|
73636
|
+
if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
|
|
73480
73637
|
continue;
|
|
73481
73638
|
}
|
|
73482
73639
|
const evaluatedCriterion = {
|
|
73483
73640
|
type: filterValue.type,
|
|
73484
|
-
values: evaluatedCriterionValues,
|
|
73641
|
+
values: evaluatedCriterionValues.map(toScalar),
|
|
73485
73642
|
dateValue: filterValue.dateValue,
|
|
73486
73643
|
};
|
|
73487
73644
|
for (let row = filteredZone.top; row <= filteredZone.bottom; row++) {
|
|
@@ -80983,26 +81140,28 @@ class SelectionStreamProcessorImpl {
|
|
|
80983
81140
|
bottom: Math.min(this.getters.getNumberRows(sheetId) - 1, bottom),
|
|
80984
81141
|
};
|
|
80985
81142
|
};
|
|
80986
|
-
const {
|
|
81143
|
+
const { cell: refCell, zone: refZone } = this.getReferenceAnchor();
|
|
81144
|
+
const { col: refCol, row: refRow } = refCell;
|
|
80987
81145
|
// check if we can shrink selection
|
|
80988
81146
|
let n = 0;
|
|
80989
81147
|
while (result !== null) {
|
|
80990
81148
|
n++;
|
|
80991
81149
|
if (deltaCol < 0) {
|
|
80992
81150
|
const newRight = this.getNextAvailableCol(deltaCol, right - (n - 1), refRow);
|
|
80993
|
-
result =
|
|
81151
|
+
result = refZone.right <= right - n ? expand({ top, left, bottom, right: newRight }) : null;
|
|
80994
81152
|
}
|
|
80995
81153
|
if (deltaCol > 0) {
|
|
80996
81154
|
const newLeft = this.getNextAvailableCol(deltaCol, left + (n - 1), refRow);
|
|
80997
|
-
result = left + n <=
|
|
81155
|
+
result = left + n <= refZone.left ? expand({ top, left: newLeft, bottom, right }) : null;
|
|
80998
81156
|
}
|
|
80999
81157
|
if (deltaRow < 0) {
|
|
81000
81158
|
const newBottom = this.getNextAvailableRow(deltaRow, refCol, bottom - (n - 1));
|
|
81001
|
-
result =
|
|
81159
|
+
result =
|
|
81160
|
+
refZone.bottom <= bottom - n ? expand({ top, left, bottom: newBottom, right }) : null;
|
|
81002
81161
|
}
|
|
81003
81162
|
if (deltaRow > 0) {
|
|
81004
81163
|
const newTop = this.getNextAvailableRow(deltaRow, refCol, top + (n - 1));
|
|
81005
|
-
result = top + n <=
|
|
81164
|
+
result = top + n <= refZone.top ? expand({ top: newTop, left, bottom, right }) : null;
|
|
81006
81165
|
}
|
|
81007
81166
|
result = result ? reorderZone(result) : result;
|
|
81008
81167
|
if (result && !isEqual(result, anchor.zone)) {
|
|
@@ -81232,18 +81391,26 @@ class SelectionStreamProcessorImpl {
|
|
|
81232
81391
|
* If the anchor is hidden, browses from left to right and top to bottom to
|
|
81233
81392
|
* find a visible cell.
|
|
81234
81393
|
*/
|
|
81235
|
-
|
|
81394
|
+
getReferenceAnchor() {
|
|
81236
81395
|
const sheetId = this.getters.getActiveSheetId();
|
|
81237
81396
|
const anchor = this.anchor;
|
|
81238
81397
|
const { left, right, top, bottom } = anchor.zone;
|
|
81239
81398
|
const { col: anchorCol, row: anchorRow } = anchor.cell;
|
|
81399
|
+
const col = this.getters.isColHidden(sheetId, anchorCol)
|
|
81400
|
+
? this.getters.findVisibleHeader(sheetId, "COL", left, right) || anchorCol
|
|
81401
|
+
: anchorCol;
|
|
81402
|
+
const row = this.getters.isRowHidden(sheetId, anchorRow)
|
|
81403
|
+
? this.getters.findVisibleHeader(sheetId, "ROW", top, bottom) || anchorRow
|
|
81404
|
+
: anchorRow;
|
|
81405
|
+
const zone = this.getters.expandZone(sheetId, {
|
|
81406
|
+
left: col,
|
|
81407
|
+
right: col,
|
|
81408
|
+
top: row,
|
|
81409
|
+
bottom: row,
|
|
81410
|
+
});
|
|
81240
81411
|
return {
|
|
81241
|
-
|
|
81242
|
-
|
|
81243
|
-
: anchorCol,
|
|
81244
|
-
row: this.getters.isRowHidden(sheetId, anchorRow)
|
|
81245
|
-
? this.getters.findVisibleHeader(sheetId, "ROW", top, bottom) || anchorRow
|
|
81246
|
-
: anchorRow,
|
|
81412
|
+
cell: { col, row },
|
|
81413
|
+
zone,
|
|
81247
81414
|
};
|
|
81248
81415
|
}
|
|
81249
81416
|
deltaToTarget(position, direction, step) {
|
|
@@ -84399,6 +84566,7 @@ const stores = {
|
|
|
84399
84566
|
PivotSidePanelStore,
|
|
84400
84567
|
PivotMeasureDisplayPanelStore,
|
|
84401
84568
|
ClientFocusStore,
|
|
84569
|
+
GridRenderer,
|
|
84402
84570
|
};
|
|
84403
84571
|
function addFunction(functionName, functionDescription) {
|
|
84404
84572
|
functionRegistry.add(functionName, functionDescription);
|
|
@@ -84465,6 +84633,6 @@ exports.tokenColors = tokenColors;
|
|
|
84465
84633
|
exports.tokenize = tokenize;
|
|
84466
84634
|
|
|
84467
84635
|
|
|
84468
|
-
__info__.version = "18.5.0-alpha.
|
|
84469
|
-
__info__.date = "2025-
|
|
84470
|
-
__info__.hash = "
|
|
84636
|
+
__info__.version = "18.5.0-alpha.2";
|
|
84637
|
+
__info__.date = "2025-07-11T11:13:53.317Z";
|
|
84638
|
+
__info__.hash = "6d42178";
|