@odoo/o-spreadsheet 18.0.43 → 18.0.45
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 +84 -47
- package/dist/o-spreadsheet.d.ts +4 -3
- package/dist/o-spreadsheet.esm.js +84 -47
- package/dist/o-spreadsheet.iife.js +84 -47
- package/dist/o-spreadsheet.iife.min.js +7 -7
- package/dist/o_spreadsheet.xml +10 -7
- package/package.json +15 -2
|
@@ -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.0.
|
|
6
|
-
* @date 2025-09-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.0.45
|
|
6
|
+
* @date 2025-09-19T07:24:19.143Z
|
|
7
|
+
* @hash 54e799a
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -854,8 +854,19 @@ function memoize(func) {
|
|
|
854
854
|
},
|
|
855
855
|
}[funcName];
|
|
856
856
|
}
|
|
857
|
+
/**
|
|
858
|
+
* Removes the specified indexes from the array.
|
|
859
|
+
* Sparse (empty) elements are transformed to undefined (unless their index is explicitly removed).
|
|
860
|
+
*/
|
|
857
861
|
function removeIndexesFromArray(array, indexes) {
|
|
858
|
-
|
|
862
|
+
const toRemove = new Set(indexes);
|
|
863
|
+
const newArray = [];
|
|
864
|
+
for (let i = 0; i < array.length; i++) {
|
|
865
|
+
if (!toRemove.has(i)) {
|
|
866
|
+
newArray.push(array[i]);
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
return newArray;
|
|
859
870
|
}
|
|
860
871
|
function insertItemsAtIndex(array, items, index) {
|
|
861
872
|
const newArray = [...array];
|
|
@@ -6739,7 +6750,7 @@ class ClipboardHandler {
|
|
|
6739
6750
|
this.getters = getters;
|
|
6740
6751
|
this.dispatch = dispatch;
|
|
6741
6752
|
}
|
|
6742
|
-
copy(data) {
|
|
6753
|
+
copy(data, mode = "copyPaste") {
|
|
6743
6754
|
return;
|
|
6744
6755
|
}
|
|
6745
6756
|
paste(target, clippedContent, options) { }
|
|
@@ -6758,7 +6769,7 @@ class ClipboardHandler {
|
|
|
6758
6769
|
}
|
|
6759
6770
|
|
|
6760
6771
|
class AbstractCellClipboardHandler extends ClipboardHandler {
|
|
6761
|
-
copy(data) {
|
|
6772
|
+
copy(data, mode = "copyPaste") {
|
|
6762
6773
|
return;
|
|
6763
6774
|
}
|
|
6764
6775
|
pasteFromCopy(sheetId, target, content, options) {
|
|
@@ -8427,7 +8438,7 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8427
8438
|
}
|
|
8428
8439
|
return "Success" /* CommandResult.Success */;
|
|
8429
8440
|
}
|
|
8430
|
-
copy(data) {
|
|
8441
|
+
copy(data, mode = "copyPaste") {
|
|
8431
8442
|
const sheetId = data.sheetId;
|
|
8432
8443
|
const { clippedZones, rowsIndexes, columnsIndexes } = data;
|
|
8433
8444
|
const clippedCells = [];
|
|
@@ -8440,7 +8451,7 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8440
8451
|
const evaluatedCell = this.getters.getEvaluatedCell(position);
|
|
8441
8452
|
const pivotId = this.getters.getPivotIdFromPosition(position);
|
|
8442
8453
|
const spreader = this.getters.getArrayFormulaSpreadingOn(position);
|
|
8443
|
-
if (pivotId && spreader) {
|
|
8454
|
+
if (mode !== "shiftCells" && pivotId && spreader) {
|
|
8444
8455
|
const pivotZone = this.getters.getSpreadZone(spreader);
|
|
8445
8456
|
if ((!deepEquals(spreader, position) || !isCopyingOneCell) &&
|
|
8446
8457
|
pivotZone &&
|
|
@@ -8458,7 +8469,7 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8458
8469
|
};
|
|
8459
8470
|
}
|
|
8460
8471
|
}
|
|
8461
|
-
else {
|
|
8472
|
+
else if (mode !== "shiftCells") {
|
|
8462
8473
|
if (spreader && !deepEquals(spreader, position)) {
|
|
8463
8474
|
const isSpreaderCopied = rowsIndexes.includes(spreader.row) && columnsIndexes.includes(spreader.col);
|
|
8464
8475
|
const content = isSpreaderCopied
|
|
@@ -9151,7 +9162,7 @@ class SheetClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
9151
9162
|
}
|
|
9152
9163
|
|
|
9153
9164
|
class TableClipboardHandler extends AbstractCellClipboardHandler {
|
|
9154
|
-
copy(data) {
|
|
9165
|
+
copy(data, mode = "copyPaste") {
|
|
9155
9166
|
const sheetId = data.sheetId;
|
|
9156
9167
|
const { rowsIndexes, columnsIndexes, zones } = data;
|
|
9157
9168
|
const copiedTablesIds = new Set();
|
|
@@ -9185,11 +9196,13 @@ class TableClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
9185
9196
|
type: coreTable.type,
|
|
9186
9197
|
};
|
|
9187
9198
|
}
|
|
9188
|
-
|
|
9189
|
-
|
|
9190
|
-
|
|
9191
|
-
|
|
9192
|
-
|
|
9199
|
+
if (mode !== "shiftCells") {
|
|
9200
|
+
tableCellsInRow.push({
|
|
9201
|
+
table: copiedTable,
|
|
9202
|
+
style: this.getTableStyleToCopy(position),
|
|
9203
|
+
isWholeTableCopied: copiedTablesIds.has(table.id),
|
|
9204
|
+
});
|
|
9205
|
+
}
|
|
9193
9206
|
}
|
|
9194
9207
|
}
|
|
9195
9208
|
return {
|
|
@@ -15095,8 +15108,9 @@ function interactiveSortSelection(env, sheetId, anchor, zone, sortDirection) {
|
|
|
15095
15108
|
}
|
|
15096
15109
|
|
|
15097
15110
|
function sortMatrix(matrix, locale, ...criteria) {
|
|
15098
|
-
for (
|
|
15099
|
-
|
|
15111
|
+
for (let i = 0; i < criteria.length; i++) {
|
|
15112
|
+
const param = i % 2 === 0 ? "sort_column" : "is_ascending";
|
|
15113
|
+
assert(() => criteria[i] !== undefined, _t("Value for parameter %s is missing in [[FUNCTION_NAME]].", param));
|
|
15100
15114
|
}
|
|
15101
15115
|
const sortingOrders = [];
|
|
15102
15116
|
const sortColumns = [];
|
|
@@ -20787,7 +20801,7 @@ const SUPPORTED_HORIZONTAL_ALIGNMENTS = [
|
|
|
20787
20801
|
];
|
|
20788
20802
|
const SUPPORTED_VERTICAL_ALIGNMENTS = ["top", "center", "bottom"];
|
|
20789
20803
|
const SUPPORTED_FONTS = ["Arial"];
|
|
20790
|
-
const SUPPORTED_FILL_PATTERNS = ["solid"];
|
|
20804
|
+
const SUPPORTED_FILL_PATTERNS = ["solid", "none"];
|
|
20791
20805
|
const SUPPORTED_CF_TYPES = [
|
|
20792
20806
|
"expression",
|
|
20793
20807
|
"cellIs",
|
|
@@ -20972,7 +20986,7 @@ const SUBTOTAL_FUNCTION_CONVERSION_MAP = {
|
|
|
20972
20986
|
};
|
|
20973
20987
|
/** Mapping between Excel format indexes (see XLSX_FORMAT_MAP) and some supported formats */
|
|
20974
20988
|
const XLSX_FORMATS_CONVERSION_MAP = {
|
|
20975
|
-
0: "",
|
|
20989
|
+
0: "General",
|
|
20976
20990
|
1: "0",
|
|
20977
20991
|
2: "0.00",
|
|
20978
20992
|
3: "#,#00",
|
|
@@ -21298,11 +21312,11 @@ const XLSX_DATE_FORMAT_REGEX = /^(yy|yyyy|m{1,5}|d{1,4}|h{1,2}|s{1,2}|am\/pm|a\/
|
|
|
21298
21312
|
* Excel format are defined in openXML §18.8.31
|
|
21299
21313
|
*/
|
|
21300
21314
|
function convertXlsxFormat(numFmtId, formats, warningManager) {
|
|
21301
|
-
if (numFmtId === 0) {
|
|
21302
|
-
return undefined;
|
|
21303
|
-
}
|
|
21304
21315
|
// Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
|
|
21305
21316
|
let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || formats.find((f) => f.id === numFmtId)?.format;
|
|
21317
|
+
if (format === "General") {
|
|
21318
|
+
return undefined;
|
|
21319
|
+
}
|
|
21306
21320
|
if (format) {
|
|
21307
21321
|
try {
|
|
21308
21322
|
let convertedFormat = format.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
|
|
@@ -24260,10 +24274,11 @@ class XlsxSheetExtractor extends XlsxBaseExtractor {
|
|
|
24260
24274
|
});
|
|
24261
24275
|
}
|
|
24262
24276
|
extractRows(worksheet) {
|
|
24277
|
+
const spilledCells = new Set();
|
|
24263
24278
|
return this.mapOnElements({ parent: worksheet, query: "sheetData row" }, (rowElement) => {
|
|
24264
24279
|
return {
|
|
24265
24280
|
index: this.extractAttr(rowElement, "r", { required: true })?.asNum(),
|
|
24266
|
-
cells: this.extractCells(rowElement),
|
|
24281
|
+
cells: this.extractCells(rowElement, spilledCells),
|
|
24267
24282
|
height: this.extractAttr(rowElement, "ht")?.asNum(),
|
|
24268
24283
|
customHeight: this.extractAttr(rowElement, "customHeight")?.asBool(),
|
|
24269
24284
|
hidden: this.extractAttr(rowElement, "hidden")?.asBool(),
|
|
@@ -24273,14 +24288,26 @@ class XlsxSheetExtractor extends XlsxBaseExtractor {
|
|
|
24273
24288
|
};
|
|
24274
24289
|
});
|
|
24275
24290
|
}
|
|
24276
|
-
extractCells(row) {
|
|
24291
|
+
extractCells(row, spilledCells) {
|
|
24277
24292
|
return this.mapOnElements({ parent: row, query: "c" }, (cellElement) => {
|
|
24293
|
+
const xc = this.extractAttr(cellElement, "r", { required: true })?.asString();
|
|
24294
|
+
const formula = this.extractCellFormula(cellElement);
|
|
24295
|
+
if (formula?.ref && formula.sharedIndex === undefined) {
|
|
24296
|
+
const zone = toZone(formula.ref);
|
|
24297
|
+
for (const { col, row } of positions(zone)) {
|
|
24298
|
+
const followerXc = toXC(col, row);
|
|
24299
|
+
if (followerXc !== xc) {
|
|
24300
|
+
spilledCells.add(followerXc);
|
|
24301
|
+
}
|
|
24302
|
+
}
|
|
24303
|
+
}
|
|
24304
|
+
const isSpilled = spilledCells.has(xc);
|
|
24278
24305
|
return {
|
|
24279
|
-
xc
|
|
24306
|
+
xc,
|
|
24280
24307
|
styleIndex: this.extractAttr(cellElement, "s")?.asNum(),
|
|
24281
24308
|
type: CELL_TYPE_CONVERSION_MAP[this.extractAttr(cellElement, "t", { default: "n" })?.asString()],
|
|
24282
|
-
value: this.extractChildTextContent(cellElement, "v"),
|
|
24283
|
-
formula:
|
|
24309
|
+
value: isSpilled ? undefined : this.extractChildTextContent(cellElement, "v") ?? undefined,
|
|
24310
|
+
formula: isSpilled ? undefined : formula,
|
|
24284
24311
|
};
|
|
24285
24312
|
});
|
|
24286
24313
|
}
|
|
@@ -24288,11 +24315,14 @@ class XlsxSheetExtractor extends XlsxBaseExtractor {
|
|
|
24288
24315
|
const formulaElement = this.querySelector(cellElement, "f");
|
|
24289
24316
|
if (!formulaElement)
|
|
24290
24317
|
return undefined;
|
|
24291
|
-
|
|
24292
|
-
|
|
24293
|
-
|
|
24294
|
-
|
|
24295
|
-
|
|
24318
|
+
const content = this.extractTextContent(formulaElement);
|
|
24319
|
+
const sharedIndex = this.extractAttr(formulaElement, "si")?.asNum();
|
|
24320
|
+
const ref = this.extractAttr(formulaElement, "ref")?.asString();
|
|
24321
|
+
// This is the case of spilled cells of array formulas where <f> is empty
|
|
24322
|
+
if ((content === undefined || content.trim() === "") && sharedIndex === undefined) {
|
|
24323
|
+
return undefined;
|
|
24324
|
+
}
|
|
24325
|
+
return { content, sharedIndex, ref };
|
|
24296
24326
|
}
|
|
24297
24327
|
extractHyperLinks(worksheet) {
|
|
24298
24328
|
return this.mapOnElements({ parent: worksheet, query: "hyperlink" }, (linkElement) => {
|
|
@@ -43445,7 +43475,7 @@ class PivotMeasureEditor extends Component {
|
|
|
43445
43475
|
});
|
|
43446
43476
|
}
|
|
43447
43477
|
get isCalculatedMeasureInvalid() {
|
|
43448
|
-
return
|
|
43478
|
+
return compile(this.props.measure.computedBy?.formula ?? "").isBadExpression;
|
|
43449
43479
|
}
|
|
43450
43480
|
}
|
|
43451
43481
|
|
|
@@ -43640,12 +43670,13 @@ class PivotLayoutConfigurator extends Component {
|
|
|
43640
43670
|
addCalculatedMeasure() {
|
|
43641
43671
|
const { measures } = this.props.definition;
|
|
43642
43672
|
const measureName = this.env.model.getters.generateNewCalculatedMeasureName(measures);
|
|
43673
|
+
const aggregator = "sum";
|
|
43643
43674
|
this.props.onDimensionsUpdated({
|
|
43644
43675
|
measures: measures.concat([
|
|
43645
43676
|
{
|
|
43646
|
-
id: this.getMeasureId(measureName),
|
|
43677
|
+
id: this.getMeasureId(measureName, aggregator),
|
|
43647
43678
|
fieldName: measureName,
|
|
43648
|
-
aggregator
|
|
43679
|
+
aggregator,
|
|
43649
43680
|
computedBy: {
|
|
43650
43681
|
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
43651
43682
|
formula: "=0",
|
|
@@ -60708,7 +60739,7 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
60708
60739
|
return { value: 0 };
|
|
60709
60740
|
}
|
|
60710
60741
|
const { columns, rows } = super.definition;
|
|
60711
|
-
if (columns.length + rows.length !== domain.length) {
|
|
60742
|
+
if (measure.aggregator && columns.length + rows.length !== domain.length) {
|
|
60712
60743
|
const values = this.getValuesToAggregate(measure, domain);
|
|
60713
60744
|
const aggregator = AGGREGATORS_FN[measure.aggregator];
|
|
60714
60745
|
if (!aggregator) {
|
|
@@ -60727,11 +60758,17 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
60727
60758
|
if (columns.find((col) => col.nameWithGranularity === symbolName)) {
|
|
60728
60759
|
const { colDomain } = domainToColRowDomain(this, domain);
|
|
60729
60760
|
const symbolIndex = colDomain.findIndex((node) => node.field === symbolName);
|
|
60761
|
+
if (symbolIndex === -1) {
|
|
60762
|
+
return new NotAvailableError();
|
|
60763
|
+
}
|
|
60730
60764
|
return this.getPivotHeaderValueAndFormat(colDomain.slice(0, symbolIndex + 1));
|
|
60731
60765
|
}
|
|
60732
60766
|
if (rows.find((row) => row.nameWithGranularity === symbolName)) {
|
|
60733
60767
|
const { rowDomain } = domainToColRowDomain(this, domain);
|
|
60734
60768
|
const symbolIndex = rowDomain.findIndex((row) => row.field === symbolName);
|
|
60769
|
+
if (symbolIndex === -1) {
|
|
60770
|
+
return new NotAvailableError();
|
|
60771
|
+
}
|
|
60735
60772
|
return this.getPivotHeaderValueAndFormat(rowDomain.slice(0, symbolIndex + 1));
|
|
60736
60773
|
}
|
|
60737
60774
|
return this.getPivotCellValueAndFormat(symbolName, domain);
|
|
@@ -65166,12 +65203,12 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
65166
65203
|
}
|
|
65167
65204
|
case "INSERT_CELL": {
|
|
65168
65205
|
const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
65169
|
-
const copiedData = this.copy(cut);
|
|
65206
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
65170
65207
|
return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
|
|
65171
65208
|
}
|
|
65172
65209
|
case "DELETE_CELL": {
|
|
65173
65210
|
const { cut, paste } = this.getDeleteCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
65174
|
-
const copiedData = this.copy(cut);
|
|
65211
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
65175
65212
|
return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
|
|
65176
65213
|
}
|
|
65177
65214
|
}
|
|
@@ -65261,13 +65298,13 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
65261
65298
|
});
|
|
65262
65299
|
break;
|
|
65263
65300
|
}
|
|
65264
|
-
const copiedData = this.copy(cut);
|
|
65301
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
65265
65302
|
this.paste(paste, copiedData, { isCutOperation: true });
|
|
65266
65303
|
break;
|
|
65267
65304
|
}
|
|
65268
65305
|
case "INSERT_CELL": {
|
|
65269
65306
|
const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
65270
|
-
const copiedData = this.copy(cut);
|
|
65307
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
65271
65308
|
this.paste(paste, copiedData, { isCutOperation: true });
|
|
65272
65309
|
break;
|
|
65273
65310
|
}
|
|
@@ -65382,11 +65419,11 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
65382
65419
|
}
|
|
65383
65420
|
return false;
|
|
65384
65421
|
}
|
|
65385
|
-
copy(zones) {
|
|
65422
|
+
copy(zones, mode = "copyPaste") {
|
|
65386
65423
|
let copiedData = {};
|
|
65387
65424
|
const clipboardData = this.getClipboardData(zones);
|
|
65388
65425
|
for (const { handlerName, handler } of this.selectClipboardHandlers(clipboardData)) {
|
|
65389
|
-
const data = handler.copy(clipboardData);
|
|
65426
|
+
const data = handler.copy(clipboardData, mode);
|
|
65390
65427
|
copiedData[handlerName] = data;
|
|
65391
65428
|
const minimalKeys = ["sheetId", "cells", "zones", "figureId"];
|
|
65392
65429
|
for (const key of minimalKeys) {
|
|
@@ -66257,7 +66294,7 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
66257
66294
|
];
|
|
66258
66295
|
for (const Handler of clipboardHandlersRegistries.cellHandlers.getAll()) {
|
|
66259
66296
|
const handler = new Handler(this.getters, this.dispatch);
|
|
66260
|
-
const data = handler.copy(getClipboardDataPositions(sheetId, target));
|
|
66297
|
+
const data = handler.copy(getClipboardDataPositions(sheetId, target), "shiftCells");
|
|
66261
66298
|
if (!data) {
|
|
66262
66299
|
continue;
|
|
66263
66300
|
}
|
|
@@ -73996,7 +74033,7 @@ class Model extends EventBus {
|
|
|
73996
74033
|
handlers = [];
|
|
73997
74034
|
uiHandlers = [];
|
|
73998
74035
|
coreHandlers = [];
|
|
73999
|
-
constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport =
|
|
74036
|
+
constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport = false) {
|
|
74000
74037
|
const start = performance.now();
|
|
74001
74038
|
console.debug("##### Model creation #####");
|
|
74002
74039
|
super();
|
|
@@ -74666,6 +74703,6 @@ const constants = {
|
|
|
74666
74703
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
74667
74704
|
|
|
74668
74705
|
|
|
74669
|
-
__info__.version = "18.0.
|
|
74670
|
-
__info__.date = "2025-09-
|
|
74671
|
-
__info__.hash = "
|
|
74706
|
+
__info__.version = "18.0.45";
|
|
74707
|
+
__info__.date = "2025-09-19T07:24:19.143Z";
|
|
74708
|
+
__info__.hash = "54e799a";
|