@odoo/o-spreadsheet 18.1.24 → 18.1.26
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 +118 -55
- package/dist/o-spreadsheet.esm.js +118 -55
- package/dist/o-spreadsheet.iife.js +118 -55
- package/dist/o-spreadsheet.iife.min.js +6 -6
- package/dist/o_spreadsheet.xml +3 -3
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 18.1.
|
|
6
|
-
* @date 2025-06-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.1.26
|
|
6
|
+
* @date 2025-06-19T18:21:37.648Z
|
|
7
|
+
* @hash 06479d4
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -5846,7 +5846,9 @@
|
|
|
5846
5846
|
}
|
|
5847
5847
|
|
|
5848
5848
|
function evaluateLiteral(literalCell, localeFormat) {
|
|
5849
|
-
const value = isTextFormat(localeFormat.format)
|
|
5849
|
+
const value = isTextFormat(localeFormat.format) && literalCell.parsedValue !== null
|
|
5850
|
+
? literalCell.content
|
|
5851
|
+
: literalCell.parsedValue;
|
|
5850
5852
|
const functionResult = { value, format: localeFormat.format };
|
|
5851
5853
|
return createEvaluatedCell(functionResult, localeFormat.locale);
|
|
5852
5854
|
}
|
|
@@ -5895,6 +5897,9 @@
|
|
|
5895
5897
|
if (isEvaluationError(value)) {
|
|
5896
5898
|
return errorCell(value, message);
|
|
5897
5899
|
}
|
|
5900
|
+
if (value === null) {
|
|
5901
|
+
return emptyCell(format);
|
|
5902
|
+
}
|
|
5898
5903
|
if (isTextFormat(format)) {
|
|
5899
5904
|
// TO DO:
|
|
5900
5905
|
// with the next line, the value of the cell is transformed depending on the format.
|
|
@@ -5902,9 +5907,6 @@
|
|
|
5902
5907
|
// to interpret the value as a number.
|
|
5903
5908
|
return textCell(toString(value), format, formattedValue);
|
|
5904
5909
|
}
|
|
5905
|
-
if (value === null) {
|
|
5906
|
-
return emptyCell(format);
|
|
5907
|
-
}
|
|
5908
5910
|
if (typeof value === "number") {
|
|
5909
5911
|
if (isDateTimeFormat(format || "")) {
|
|
5910
5912
|
return dateTimeCell(value, format, formattedValue);
|
|
@@ -10201,6 +10203,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10201
10203
|
if (isTrendLineAxis(dataset.xAxisID) || dataset.hidden) {
|
|
10202
10204
|
continue;
|
|
10203
10205
|
}
|
|
10206
|
+
const yAxisScale = chart.scales[dataset.yAxisID];
|
|
10204
10207
|
for (let i = 0; i < dataset._parsed.length; i++) {
|
|
10205
10208
|
const parsedValue = dataset._parsed[i];
|
|
10206
10209
|
const value = Number(chart.config.type === "radar" ? parsedValue.r : parsedValue.y);
|
|
@@ -10211,10 +10214,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10211
10214
|
const xPosition = point.x;
|
|
10212
10215
|
let yPosition = 0;
|
|
10213
10216
|
if (chart.config.type === "line" || chart.config.type === "radar") {
|
|
10214
|
-
yPosition = point.y - 10;
|
|
10217
|
+
yPosition = value < 0 ? point.y + 10 : point.y - 10;
|
|
10215
10218
|
}
|
|
10216
10219
|
else {
|
|
10217
|
-
|
|
10220
|
+
const yZeroLine = yAxisScale.getPixelForValue(0);
|
|
10221
|
+
const distanceFromAxisOrigin = Math.abs(yZeroLine - point.y);
|
|
10222
|
+
const textHeight = 12; // ChartJS default text height
|
|
10223
|
+
if (distanceFromAxisOrigin < textHeight) {
|
|
10224
|
+
yPosition = value < 0 ? yZeroLine + textHeight / 2 : yZeroLine - textHeight / 2;
|
|
10225
|
+
}
|
|
10226
|
+
else {
|
|
10227
|
+
yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
|
|
10228
|
+
}
|
|
10218
10229
|
}
|
|
10219
10230
|
yPosition = Math.min(yPosition, yMax);
|
|
10220
10231
|
yPosition = Math.max(yPosition, yMin);
|
|
@@ -10224,7 +10235,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10224
10235
|
}
|
|
10225
10236
|
for (const otherPosition of textsPositions[xPosition] || []) {
|
|
10226
10237
|
if (Math.abs(otherPosition - yPosition) < 13) {
|
|
10227
|
-
yPosition = otherPosition - 13;
|
|
10238
|
+
yPosition = value < 0 ? otherPosition + 13 : otherPosition - 13;
|
|
10228
10239
|
}
|
|
10229
10240
|
}
|
|
10230
10241
|
textsPositions[xPosition].push(yPosition);
|
|
@@ -10243,6 +10254,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10243
10254
|
if (isTrendLineAxis(dataset.xAxisID)) {
|
|
10244
10255
|
return; // ignore trend lines
|
|
10245
10256
|
}
|
|
10257
|
+
const xAxisScale = chart.scales[dataset.xAxisID];
|
|
10258
|
+
const xZeroLine = xAxisScale.getPixelForValue(0);
|
|
10246
10259
|
for (let i = 0; i < dataset._parsed.length; i++) {
|
|
10247
10260
|
const value = Number(dataset._parsed[i].x);
|
|
10248
10261
|
if (isNaN(value)) {
|
|
@@ -10251,17 +10264,27 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10251
10264
|
const displayValue = options.callback(value, dataset, i);
|
|
10252
10265
|
const point = dataset.data[i];
|
|
10253
10266
|
const yPosition = point.y;
|
|
10254
|
-
|
|
10255
|
-
|
|
10256
|
-
|
|
10267
|
+
const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
|
|
10268
|
+
const distanceFromAxisOrigin = Math.abs(point.x - xZeroLine);
|
|
10269
|
+
const PADDING = 3;
|
|
10270
|
+
let xPosition;
|
|
10271
|
+
if (distanceFromAxisOrigin < textWidth) {
|
|
10272
|
+
xPosition =
|
|
10273
|
+
value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
|
|
10274
|
+
}
|
|
10275
|
+
else {
|
|
10276
|
+
xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
|
|
10277
|
+
xPosition = Math.min(xPosition, xMax);
|
|
10278
|
+
xPosition = Math.max(xPosition, xMin);
|
|
10279
|
+
}
|
|
10257
10280
|
// Avoid overlapping texts with same Y
|
|
10258
10281
|
if (!textsPositions[yPosition]) {
|
|
10259
10282
|
textsPositions[yPosition] = [];
|
|
10260
10283
|
}
|
|
10261
|
-
const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
|
|
10262
10284
|
for (const otherPosition of textsPositions[yPosition]) {
|
|
10263
10285
|
if (Math.abs(otherPosition - xPosition) < textWidth) {
|
|
10264
|
-
xPosition =
|
|
10286
|
+
xPosition =
|
|
10287
|
+
value < 0 ? otherPosition - textWidth - PADDING : otherPosition + textWidth + PADDING;
|
|
10265
10288
|
}
|
|
10266
10289
|
}
|
|
10267
10290
|
textsPositions[yPosition].push(xPosition);
|
|
@@ -10283,10 +10306,22 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10283
10306
|
const midAngle = (startAngle + endAngle) / 2;
|
|
10284
10307
|
const midRadius = (innerRadius + outerRadius) / 2;
|
|
10285
10308
|
const x = bar.x + midRadius * Math.cos(midAngle);
|
|
10286
|
-
const y = bar.y + midRadius * Math.sin(midAngle)
|
|
10309
|
+
const y = bar.y + midRadius * Math.sin(midAngle);
|
|
10310
|
+
const displayValue = options.callback(value, dataset, i);
|
|
10311
|
+
const textHeight = 12; // ChartJS default
|
|
10312
|
+
const textWidth = computeTextWidth(ctx, displayValue, { fontSize: textHeight }, "px");
|
|
10313
|
+
const radius = outerRadius - innerRadius;
|
|
10314
|
+
// Check if the text fits in the slice. Not perfect, but good enough heuristic.
|
|
10315
|
+
if (textWidth >= radius || radius < textHeight) {
|
|
10316
|
+
continue;
|
|
10317
|
+
}
|
|
10318
|
+
const sliceAngle = endAngle - startAngle;
|
|
10319
|
+
const midWidth = 2 * midRadius * Math.tan(sliceAngle / 2);
|
|
10320
|
+
if (sliceAngle < Math.PI / 2 && (textWidth >= midWidth || midWidth < textHeight)) {
|
|
10321
|
+
continue;
|
|
10322
|
+
}
|
|
10287
10323
|
ctx.fillStyle = chartFontColor(options.background);
|
|
10288
10324
|
ctx.strokeStyle = options.background || "#ffffff";
|
|
10289
|
-
const displayValue = options.callback(value, dataset, i);
|
|
10290
10325
|
drawTextWithBackground(displayValue, x, y, ctx);
|
|
10291
10326
|
}
|
|
10292
10327
|
}
|
|
@@ -26192,7 +26227,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
26192
26227
|
*/
|
|
26193
26228
|
handleMissingValue(parentElement, missingElementName, optionalArgs) {
|
|
26194
26229
|
if (optionalArgs?.required) {
|
|
26195
|
-
if (optionalArgs?.default) {
|
|
26230
|
+
if (optionalArgs?.default !== undefined) {
|
|
26196
26231
|
this.warningManager.addParsingWarning(`Missing required ${missingElementName} in element <${parentElement.tagName}> of ${this.currentFile}, replacing it by the default value ${optionalArgs.default}`);
|
|
26197
26232
|
}
|
|
26198
26233
|
else {
|
|
@@ -30065,7 +30100,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
30065
30100
|
background: definition.background,
|
|
30066
30101
|
callback: (value, dataset) => {
|
|
30067
30102
|
value = Math.abs(Number(value));
|
|
30068
|
-
return
|
|
30103
|
+
return value === 0
|
|
30104
|
+
? ""
|
|
30105
|
+
: formatChartDatasetValue(axisFormats, locale)(value, dataset.xAxisID || "x");
|
|
30069
30106
|
},
|
|
30070
30107
|
};
|
|
30071
30108
|
}
|
|
@@ -33214,19 +33251,26 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
33214
33251
|
.filter(({ row }) => !this.env.model.getters.isRowHidden(sheetId, row))
|
|
33215
33252
|
.map(({ col, row }) => this.env.model.getters.getEvaluatedCell({ sheetId, col, row }).formattedValue);
|
|
33216
33253
|
const filterValues = this.env.model.getters.getFilterHiddenValues({ sheetId, ...position });
|
|
33217
|
-
const
|
|
33218
|
-
const
|
|
33219
|
-
|
|
33220
|
-
const
|
|
33221
|
-
|
|
33222
|
-
|
|
33223
|
-
|
|
33224
|
-
|
|
33225
|
-
|
|
33226
|
-
|
|
33227
|
-
|
|
33228
|
-
|
|
33229
|
-
|
|
33254
|
+
const normalizedFilteredValues = new Set(filterValues.map(toLowerCase));
|
|
33255
|
+
const set = new Set();
|
|
33256
|
+
const values = [];
|
|
33257
|
+
const addValue = (value) => {
|
|
33258
|
+
const normalizedValue = toLowerCase(value);
|
|
33259
|
+
if (!set.has(normalizedValue)) {
|
|
33260
|
+
values.push({
|
|
33261
|
+
string: value || "",
|
|
33262
|
+
checked: !normalizedFilteredValues.has(normalizedValue),
|
|
33263
|
+
normalizedValue,
|
|
33264
|
+
});
|
|
33265
|
+
set.add(normalizedValue);
|
|
33266
|
+
}
|
|
33267
|
+
};
|
|
33268
|
+
cellValues.forEach(addValue);
|
|
33269
|
+
filterValues.forEach(addValue);
|
|
33270
|
+
return values.sort((val1, val2) => val1.normalizedValue.localeCompare(val2.normalizedValue, undefined, {
|
|
33271
|
+
numeric: true,
|
|
33272
|
+
sensitivity: "base",
|
|
33273
|
+
}));
|
|
33230
33274
|
}
|
|
33231
33275
|
checkValue(value) {
|
|
33232
33276
|
this.state.selectedValue = value.string;
|
|
@@ -34558,6 +34602,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34558
34602
|
});
|
|
34559
34603
|
};
|
|
34560
34604
|
const CAN_REMOVE_COLUMNS_ROWS = (dimension, env) => {
|
|
34605
|
+
if ((dimension === "COL" && env.model.getters.getActiveRows().size > 0) ||
|
|
34606
|
+
(dimension === "ROW" && env.model.getters.getActiveCols().size > 0)) {
|
|
34607
|
+
return false;
|
|
34608
|
+
}
|
|
34561
34609
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
34562
34610
|
const selectedElements = env.model.getters.getElementsFromSelection(dimension);
|
|
34563
34611
|
const includesAllVisibleHeaders = env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, dimension, selectedElements);
|
|
@@ -37537,11 +37585,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
37537
37585
|
* transformation function given
|
|
37538
37586
|
*/
|
|
37539
37587
|
addTransformation(executed, toTransforms, fn) {
|
|
37540
|
-
|
|
37541
|
-
|
|
37542
|
-
|
|
37543
|
-
|
|
37544
|
-
this.content[
|
|
37588
|
+
if (!this.content[executed]) {
|
|
37589
|
+
this.content[executed] = new Map();
|
|
37590
|
+
}
|
|
37591
|
+
for (const toTransform of toTransforms) {
|
|
37592
|
+
this.content[executed].set(toTransform, fn);
|
|
37545
37593
|
}
|
|
37546
37594
|
return this;
|
|
37547
37595
|
}
|
|
@@ -37550,7 +37598,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
37550
37598
|
* that the executed command happened.
|
|
37551
37599
|
*/
|
|
37552
37600
|
getTransformation(toTransform, executed) {
|
|
37553
|
-
return this.content[
|
|
37601
|
+
return this.content[executed] && this.content[executed].get(toTransform);
|
|
37554
37602
|
}
|
|
37555
37603
|
}
|
|
37556
37604
|
const otRegistry = new OTRegistry();
|
|
@@ -58094,7 +58142,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
58094
58142
|
const ranges = cmd.ranges.map((rangeData) => this.getters.getRangeFromRangeData(rangeData));
|
|
58095
58143
|
const union = this.getters.getRangesUnion(ranges);
|
|
58096
58144
|
const mergesInTarget = this.getters.getMergesInZone(cmd.sheetId, union.zone);
|
|
58097
|
-
|
|
58145
|
+
if (mergesInTarget.length) {
|
|
58146
|
+
this.dispatch("REMOVE_MERGE", { sheetId: cmd.sheetId, target: mergesInTarget });
|
|
58147
|
+
}
|
|
58098
58148
|
const id = `${nextTableId++}`;
|
|
58099
58149
|
const config = cmd.config || DEFAULT_TABLE_CONFIG;
|
|
58100
58150
|
const newTable = cmd.tableType === "dynamic"
|
|
@@ -58205,14 +58255,16 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
58205
58255
|
const zoneToCheckIfEmpty = direction === "down"
|
|
58206
58256
|
? { ...zone, bottom: zone.bottom + 1, top: zone.bottom + 1 }
|
|
58207
58257
|
: { ...zone, right: zone.right + 1, left: zone.right + 1 };
|
|
58208
|
-
for (
|
|
58209
|
-
|
|
58210
|
-
|
|
58211
|
-
|
|
58212
|
-
|
|
58213
|
-
|
|
58214
|
-
|
|
58215
|
-
|
|
58258
|
+
for (let row = zoneToCheckIfEmpty.top; row <= zoneToCheckIfEmpty.bottom; row++) {
|
|
58259
|
+
for (let col = zoneToCheckIfEmpty.left; col <= zoneToCheckIfEmpty.right; col++) {
|
|
58260
|
+
const cellPosition = { sheetId, col, row };
|
|
58261
|
+
// Since this plugin is loaded before CellPlugin, the getters still give us the old cell content
|
|
58262
|
+
const cellContent = this.getters.getCell(cellPosition)?.content;
|
|
58263
|
+
if (cellContent ||
|
|
58264
|
+
this.getters.isInMerge(cellPosition) ||
|
|
58265
|
+
this.getTablesOverlappingZones(sheetId, [positionToZone(cellPosition)]).length) {
|
|
58266
|
+
return "none";
|
|
58267
|
+
}
|
|
58216
58268
|
}
|
|
58217
58269
|
}
|
|
58218
58270
|
return direction;
|
|
@@ -64241,10 +64293,20 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
64241
64293
|
*/
|
|
64242
64294
|
function transformAll(toTransform, executed) {
|
|
64243
64295
|
let transformedCommands = [...toTransform];
|
|
64296
|
+
const possibleTransformations = new Set(otRegistry.getKeys());
|
|
64244
64297
|
for (const executedCommand of executed) {
|
|
64245
|
-
|
|
64246
|
-
|
|
64247
|
-
|
|
64298
|
+
// If the executed command is not in the registry, we skip it
|
|
64299
|
+
// because we know there won't be any transformation impacting the
|
|
64300
|
+
// commands to transform.
|
|
64301
|
+
if (possibleTransformations.has(executedCommand.type)) {
|
|
64302
|
+
transformedCommands = transformedCommands.reduce((acc, cmd) => {
|
|
64303
|
+
const transformed = transform(cmd, executedCommand);
|
|
64304
|
+
if (transformed) {
|
|
64305
|
+
acc.push(transformed);
|
|
64306
|
+
}
|
|
64307
|
+
return acc;
|
|
64308
|
+
}, []);
|
|
64309
|
+
}
|
|
64248
64310
|
}
|
|
64249
64311
|
return transformedCommands;
|
|
64250
64312
|
}
|
|
@@ -65939,7 +66001,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
65939
66001
|
}
|
|
65940
66002
|
const position = this.getters.getCellPosition(cell.id);
|
|
65941
66003
|
const colSize = this.getters.getColSize(sheetId, position.col);
|
|
65942
|
-
if (cell.isFormula) {
|
|
66004
|
+
if (cell.isFormula || this.getters.getArrayFormulaSpreadingOn(position)) {
|
|
65943
66005
|
const content = this.getters.getEvaluatedCell(position).formattedValue;
|
|
65944
66006
|
const evaluatedSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
|
|
65945
66007
|
if (evaluatedSize > evaluatedRowSize && evaluatedSize > DEFAULT_CELL_HEIGHT) {
|
|
@@ -67578,9 +67640,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67578
67640
|
const filteredZone = filter.filteredRange?.zone;
|
|
67579
67641
|
if (!filteredValues || !filteredZone)
|
|
67580
67642
|
continue;
|
|
67643
|
+
const filteredValuesSet = new Set(filteredValues);
|
|
67581
67644
|
for (let row = filteredZone.top; row <= filteredZone.bottom; row++) {
|
|
67582
67645
|
const value = this.getCellValueAsString(sheetId, filter.col, row);
|
|
67583
|
-
if (
|
|
67646
|
+
if (filteredValuesSet.has(value)) {
|
|
67584
67647
|
hiddenRows.add(row);
|
|
67585
67648
|
}
|
|
67586
67649
|
}
|
|
@@ -76510,9 +76573,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
76510
76573
|
exports.tokenize = tokenize;
|
|
76511
76574
|
|
|
76512
76575
|
|
|
76513
|
-
__info__.version = "18.1.
|
|
76514
|
-
__info__.date = "2025-06-
|
|
76515
|
-
__info__.hash = "
|
|
76576
|
+
__info__.version = "18.1.26";
|
|
76577
|
+
__info__.date = "2025-06-19T18:21:37.648Z";
|
|
76578
|
+
__info__.hash = "06479d4";
|
|
76516
76579
|
|
|
76517
76580
|
|
|
76518
76581
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|