@odoo/o-spreadsheet 18.2.16 → 18.2.18
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 +114 -114
- 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.2.
|
|
6
|
-
* @date 2025-06-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.2.18
|
|
6
|
+
* @date 2025-06-19T18:24:41.051Z
|
|
7
|
+
* @hash 024c134
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -5855,7 +5855,9 @@
|
|
|
5855
5855
|
}
|
|
5856
5856
|
|
|
5857
5857
|
function evaluateLiteral(literalCell, localeFormat) {
|
|
5858
|
-
const value = isTextFormat(localeFormat.format)
|
|
5858
|
+
const value = isTextFormat(localeFormat.format) && literalCell.parsedValue !== null
|
|
5859
|
+
? literalCell.content
|
|
5860
|
+
: literalCell.parsedValue;
|
|
5859
5861
|
const functionResult = { value, format: localeFormat.format };
|
|
5860
5862
|
return createEvaluatedCell(functionResult, localeFormat.locale);
|
|
5861
5863
|
}
|
|
@@ -5904,6 +5906,9 @@
|
|
|
5904
5906
|
if (isEvaluationError(value)) {
|
|
5905
5907
|
return errorCell(value, message);
|
|
5906
5908
|
}
|
|
5909
|
+
if (value === null) {
|
|
5910
|
+
return emptyCell(format);
|
|
5911
|
+
}
|
|
5907
5912
|
if (isTextFormat(format)) {
|
|
5908
5913
|
// TO DO:
|
|
5909
5914
|
// with the next line, the value of the cell is transformed depending on the format.
|
|
@@ -5911,9 +5916,6 @@
|
|
|
5911
5916
|
// to interpret the value as a number.
|
|
5912
5917
|
return textCell(toString(value), format, formattedValue);
|
|
5913
5918
|
}
|
|
5914
|
-
if (value === null) {
|
|
5915
|
-
return emptyCell(format);
|
|
5916
|
-
}
|
|
5917
5919
|
if (typeof value === "number") {
|
|
5918
5920
|
if (isDateTimeFormat(format || "")) {
|
|
5919
5921
|
return dateTimeCell(value, format, formattedValue);
|
|
@@ -10365,6 +10367,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10365
10367
|
if (isTrendLineAxis(dataset.xAxisID) || dataset.hidden) {
|
|
10366
10368
|
continue;
|
|
10367
10369
|
}
|
|
10370
|
+
const yAxisScale = chart.scales[dataset.yAxisID];
|
|
10368
10371
|
for (let i = 0; i < dataset._parsed.length; i++) {
|
|
10369
10372
|
const parsedValue = dataset._parsed[i];
|
|
10370
10373
|
const value = Number(chart.config.type === "radar" ? parsedValue.r : parsedValue.y);
|
|
@@ -10375,10 +10378,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10375
10378
|
const xPosition = point.x;
|
|
10376
10379
|
let yPosition = 0;
|
|
10377
10380
|
if (chart.config.type === "line" || chart.config.type === "radar") {
|
|
10378
|
-
yPosition = point.y - 10;
|
|
10381
|
+
yPosition = value < 0 ? point.y + 10 : point.y - 10;
|
|
10379
10382
|
}
|
|
10380
10383
|
else {
|
|
10381
|
-
|
|
10384
|
+
const yZeroLine = yAxisScale.getPixelForValue(0);
|
|
10385
|
+
const distanceFromAxisOrigin = Math.abs(yZeroLine - point.y);
|
|
10386
|
+
const textHeight = 12; // ChartJS default text height
|
|
10387
|
+
if (distanceFromAxisOrigin < textHeight) {
|
|
10388
|
+
yPosition = value < 0 ? yZeroLine + textHeight / 2 : yZeroLine - textHeight / 2;
|
|
10389
|
+
}
|
|
10390
|
+
else {
|
|
10391
|
+
yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
|
|
10392
|
+
}
|
|
10382
10393
|
}
|
|
10383
10394
|
yPosition = Math.min(yPosition, yMax);
|
|
10384
10395
|
yPosition = Math.max(yPosition, yMin);
|
|
@@ -10388,7 +10399,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10388
10399
|
}
|
|
10389
10400
|
for (const otherPosition of textsPositions[xPosition] || []) {
|
|
10390
10401
|
if (Math.abs(otherPosition - yPosition) < 13) {
|
|
10391
|
-
yPosition = otherPosition - 13;
|
|
10402
|
+
yPosition = value < 0 ? otherPosition + 13 : otherPosition - 13;
|
|
10392
10403
|
}
|
|
10393
10404
|
}
|
|
10394
10405
|
textsPositions[xPosition].push(yPosition);
|
|
@@ -10407,6 +10418,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10407
10418
|
if (isTrendLineAxis(dataset.xAxisID)) {
|
|
10408
10419
|
return; // ignore trend lines
|
|
10409
10420
|
}
|
|
10421
|
+
const xAxisScale = chart.scales[dataset.xAxisID];
|
|
10422
|
+
const xZeroLine = xAxisScale.getPixelForValue(0);
|
|
10410
10423
|
for (let i = 0; i < dataset._parsed.length; i++) {
|
|
10411
10424
|
const value = Number(dataset._parsed[i].x);
|
|
10412
10425
|
if (isNaN(value)) {
|
|
@@ -10415,17 +10428,27 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10415
10428
|
const displayValue = options.callback(value, dataset, i);
|
|
10416
10429
|
const point = dataset.data[i];
|
|
10417
10430
|
const yPosition = point.y;
|
|
10418
|
-
|
|
10419
|
-
|
|
10420
|
-
|
|
10431
|
+
const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
|
|
10432
|
+
const distanceFromAxisOrigin = Math.abs(point.x - xZeroLine);
|
|
10433
|
+
const PADDING = 3;
|
|
10434
|
+
let xPosition;
|
|
10435
|
+
if (distanceFromAxisOrigin < textWidth) {
|
|
10436
|
+
xPosition =
|
|
10437
|
+
value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
|
|
10438
|
+
}
|
|
10439
|
+
else {
|
|
10440
|
+
xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
|
|
10441
|
+
xPosition = Math.min(xPosition, xMax);
|
|
10442
|
+
xPosition = Math.max(xPosition, xMin);
|
|
10443
|
+
}
|
|
10421
10444
|
// Avoid overlapping texts with same Y
|
|
10422
10445
|
if (!textsPositions[yPosition]) {
|
|
10423
10446
|
textsPositions[yPosition] = [];
|
|
10424
10447
|
}
|
|
10425
|
-
const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
|
|
10426
10448
|
for (const otherPosition of textsPositions[yPosition]) {
|
|
10427
10449
|
if (Math.abs(otherPosition - xPosition) < textWidth) {
|
|
10428
|
-
xPosition =
|
|
10450
|
+
xPosition =
|
|
10451
|
+
value < 0 ? otherPosition - textWidth - PADDING : otherPosition + textWidth + PADDING;
|
|
10429
10452
|
}
|
|
10430
10453
|
}
|
|
10431
10454
|
textsPositions[yPosition].push(xPosition);
|
|
@@ -10447,10 +10470,22 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10447
10470
|
const midAngle = (startAngle + endAngle) / 2;
|
|
10448
10471
|
const midRadius = (innerRadius + outerRadius) / 2;
|
|
10449
10472
|
const x = bar.x + midRadius * Math.cos(midAngle);
|
|
10450
|
-
const y = bar.y + midRadius * Math.sin(midAngle)
|
|
10473
|
+
const y = bar.y + midRadius * Math.sin(midAngle);
|
|
10474
|
+
const displayValue = options.callback(value, dataset, i);
|
|
10475
|
+
const textHeight = 12; // ChartJS default
|
|
10476
|
+
const textWidth = computeTextWidth(ctx, displayValue, { fontSize: textHeight }, "px");
|
|
10477
|
+
const radius = outerRadius - innerRadius;
|
|
10478
|
+
// Check if the text fits in the slice. Not perfect, but good enough heuristic.
|
|
10479
|
+
if (textWidth >= radius || radius < textHeight) {
|
|
10480
|
+
continue;
|
|
10481
|
+
}
|
|
10482
|
+
const sliceAngle = endAngle - startAngle;
|
|
10483
|
+
const midWidth = 2 * midRadius * Math.tan(sliceAngle / 2);
|
|
10484
|
+
if (sliceAngle < Math.PI / 2 && (textWidth >= midWidth || midWidth < textHeight)) {
|
|
10485
|
+
continue;
|
|
10486
|
+
}
|
|
10451
10487
|
ctx.fillStyle = chartFontColor(options.background);
|
|
10452
10488
|
ctx.strokeStyle = options.background || "#ffffff";
|
|
10453
|
-
const displayValue = options.callback(value, dataset, i);
|
|
10454
10489
|
drawTextWithBackground(displayValue, x, y, ctx);
|
|
10455
10490
|
}
|
|
10456
10491
|
}
|
|
@@ -26216,7 +26251,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
26216
26251
|
*/
|
|
26217
26252
|
handleMissingValue(parentElement, missingElementName, optionalArgs) {
|
|
26218
26253
|
if (optionalArgs?.required) {
|
|
26219
|
-
if (optionalArgs?.default) {
|
|
26254
|
+
if (optionalArgs?.default !== undefined) {
|
|
26220
26255
|
this.warningManager.addParsingWarning(`Missing required ${missingElementName} in element <${parentElement.tagName}> of ${this.currentFile}, replacing it by the default value ${optionalArgs.default}`);
|
|
26221
26256
|
}
|
|
26222
26257
|
else {
|
|
@@ -30097,7 +30132,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
30097
30132
|
background: definition.background,
|
|
30098
30133
|
callback: (value, dataset) => {
|
|
30099
30134
|
value = Math.abs(Number(value));
|
|
30100
|
-
return
|
|
30135
|
+
return value === 0
|
|
30136
|
+
? ""
|
|
30137
|
+
: formatChartDatasetValue(axisFormats, locale)(value, dataset.xAxisID || "x");
|
|
30101
30138
|
},
|
|
30102
30139
|
};
|
|
30103
30140
|
}
|
|
@@ -33413,19 +33450,26 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
33413
33450
|
.filter(({ row }) => !this.env.model.getters.isRowHidden(sheetId, row))
|
|
33414
33451
|
.map(({ col, row }) => this.env.model.getters.getEvaluatedCell({ sheetId, col, row }).formattedValue);
|
|
33415
33452
|
const filterValues = this.env.model.getters.getFilterHiddenValues({ sheetId, ...position });
|
|
33416
|
-
const
|
|
33417
|
-
const
|
|
33418
|
-
|
|
33419
|
-
const
|
|
33420
|
-
|
|
33421
|
-
|
|
33422
|
-
|
|
33423
|
-
|
|
33424
|
-
|
|
33425
|
-
|
|
33426
|
-
|
|
33427
|
-
|
|
33428
|
-
|
|
33453
|
+
const normalizedFilteredValues = new Set(filterValues.map(toLowerCase));
|
|
33454
|
+
const set = new Set();
|
|
33455
|
+
const values = [];
|
|
33456
|
+
const addValue = (value) => {
|
|
33457
|
+
const normalizedValue = toLowerCase(value);
|
|
33458
|
+
if (!set.has(normalizedValue)) {
|
|
33459
|
+
values.push({
|
|
33460
|
+
string: value || "",
|
|
33461
|
+
checked: !normalizedFilteredValues.has(normalizedValue),
|
|
33462
|
+
normalizedValue,
|
|
33463
|
+
});
|
|
33464
|
+
set.add(normalizedValue);
|
|
33465
|
+
}
|
|
33466
|
+
};
|
|
33467
|
+
cellValues.forEach(addValue);
|
|
33468
|
+
filterValues.forEach(addValue);
|
|
33469
|
+
return values.sort((val1, val2) => val1.normalizedValue.localeCompare(val2.normalizedValue, undefined, {
|
|
33470
|
+
numeric: true,
|
|
33471
|
+
sensitivity: "base",
|
|
33472
|
+
}));
|
|
33429
33473
|
}
|
|
33430
33474
|
checkValue(value) {
|
|
33431
33475
|
this.state.selectedValue = value.string;
|
|
@@ -34759,6 +34803,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34759
34803
|
});
|
|
34760
34804
|
};
|
|
34761
34805
|
const CAN_REMOVE_COLUMNS_ROWS = (dimension, env) => {
|
|
34806
|
+
if ((dimension === "COL" && env.model.getters.getActiveRows().size > 0) ||
|
|
34807
|
+
(dimension === "ROW" && env.model.getters.getActiveCols().size > 0)) {
|
|
34808
|
+
return false;
|
|
34809
|
+
}
|
|
34762
34810
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
34763
34811
|
const selectedElements = env.model.getters.getElementsFromSelection(dimension);
|
|
34764
34812
|
const includesAllVisibleHeaders = env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, dimension, selectedElements);
|
|
@@ -37738,11 +37786,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
37738
37786
|
* transformation function given
|
|
37739
37787
|
*/
|
|
37740
37788
|
addTransformation(executed, toTransforms, fn) {
|
|
37741
|
-
|
|
37742
|
-
|
|
37743
|
-
|
|
37744
|
-
|
|
37745
|
-
this.content[
|
|
37789
|
+
if (!this.content[executed]) {
|
|
37790
|
+
this.content[executed] = new Map();
|
|
37791
|
+
}
|
|
37792
|
+
for (const toTransform of toTransforms) {
|
|
37793
|
+
this.content[executed].set(toTransform, fn);
|
|
37746
37794
|
}
|
|
37747
37795
|
return this;
|
|
37748
37796
|
}
|
|
@@ -37751,7 +37799,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
37751
37799
|
* that the executed command happened.
|
|
37752
37800
|
*/
|
|
37753
37801
|
getTransformation(toTransform, executed) {
|
|
37754
|
-
return this.content[
|
|
37802
|
+
return this.content[executed] && this.content[executed].get(toTransform);
|
|
37755
37803
|
}
|
|
37756
37804
|
}
|
|
37757
37805
|
const otRegistry = new OTRegistry();
|
|
@@ -58592,7 +58640,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
58592
58640
|
const ranges = cmd.ranges.map((rangeData) => this.getters.getRangeFromRangeData(rangeData));
|
|
58593
58641
|
const union = this.getters.getRangesUnion(ranges);
|
|
58594
58642
|
const mergesInTarget = this.getters.getMergesInZone(cmd.sheetId, union.zone);
|
|
58595
|
-
|
|
58643
|
+
if (mergesInTarget.length) {
|
|
58644
|
+
this.dispatch("REMOVE_MERGE", { sheetId: cmd.sheetId, target: mergesInTarget });
|
|
58645
|
+
}
|
|
58596
58646
|
const id = this.consumeNextId();
|
|
58597
58647
|
const config = cmd.config || DEFAULT_TABLE_CONFIG;
|
|
58598
58648
|
const newTable = cmd.tableType === "dynamic"
|
|
@@ -58691,14 +58741,16 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
58691
58741
|
const zoneToCheckIfEmpty = direction === "down"
|
|
58692
58742
|
? { ...zone, bottom: zone.bottom + 1, top: zone.bottom + 1 }
|
|
58693
58743
|
: { ...zone, right: zone.right + 1, left: zone.right + 1 };
|
|
58694
|
-
for (
|
|
58695
|
-
|
|
58696
|
-
|
|
58697
|
-
|
|
58698
|
-
|
|
58699
|
-
|
|
58700
|
-
|
|
58701
|
-
|
|
58744
|
+
for (let row = zoneToCheckIfEmpty.top; row <= zoneToCheckIfEmpty.bottom; row++) {
|
|
58745
|
+
for (let col = zoneToCheckIfEmpty.left; col <= zoneToCheckIfEmpty.right; col++) {
|
|
58746
|
+
const cellPosition = { sheetId, col, row };
|
|
58747
|
+
// Since this plugin is loaded before CellPlugin, the getters still give us the old cell content
|
|
58748
|
+
const cellContent = this.getters.getCell(cellPosition)?.content;
|
|
58749
|
+
if (cellContent ||
|
|
58750
|
+
this.getters.isInMerge(cellPosition) ||
|
|
58751
|
+
this.getTablesOverlappingZones(sheetId, [positionToZone(cellPosition)]).length) {
|
|
58752
|
+
return "none";
|
|
58753
|
+
}
|
|
58702
58754
|
}
|
|
58703
58755
|
}
|
|
58704
58756
|
return direction;
|
|
@@ -64741,10 +64793,20 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
64741
64793
|
*/
|
|
64742
64794
|
function transformAll(toTransform, executed) {
|
|
64743
64795
|
let transformedCommands = [...toTransform];
|
|
64796
|
+
const possibleTransformations = new Set(otRegistry.getKeys());
|
|
64744
64797
|
for (const executedCommand of executed) {
|
|
64745
|
-
|
|
64746
|
-
|
|
64747
|
-
|
|
64798
|
+
// If the executed command is not in the registry, we skip it
|
|
64799
|
+
// because we know there won't be any transformation impacting the
|
|
64800
|
+
// commands to transform.
|
|
64801
|
+
if (possibleTransformations.has(executedCommand.type)) {
|
|
64802
|
+
transformedCommands = transformedCommands.reduce((acc, cmd) => {
|
|
64803
|
+
const transformed = transform(cmd, executedCommand);
|
|
64804
|
+
if (transformed) {
|
|
64805
|
+
acc.push(transformed);
|
|
64806
|
+
}
|
|
64807
|
+
return acc;
|
|
64808
|
+
}, []);
|
|
64809
|
+
}
|
|
64748
64810
|
}
|
|
64749
64811
|
return transformedCommands;
|
|
64750
64812
|
}
|
|
@@ -66433,7 +66495,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
66433
66495
|
}
|
|
66434
66496
|
const position = this.getters.getCellPosition(cell.id);
|
|
66435
66497
|
const colSize = this.getters.getColSize(sheetId, position.col);
|
|
66436
|
-
if (cell.isFormula) {
|
|
66498
|
+
if (cell.isFormula || this.getters.getArrayFormulaSpreadingOn(position)) {
|
|
66437
66499
|
const content = this.getters.getEvaluatedCell(position).formattedValue;
|
|
66438
66500
|
const evaluatedSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
|
|
66439
66501
|
if (evaluatedSize > evaluatedRowSize && evaluatedSize > DEFAULT_CELL_HEIGHT) {
|
|
@@ -68072,9 +68134,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68072
68134
|
const filteredZone = filter.filteredRange?.zone;
|
|
68073
68135
|
if (!filteredValues || !filteredZone)
|
|
68074
68136
|
continue;
|
|
68137
|
+
const filteredValuesSet = new Set(filteredValues);
|
|
68075
68138
|
for (let row = filteredZone.top; row <= filteredZone.bottom; row++) {
|
|
68076
68139
|
const value = this.getCellValueAsString(sheetId, filter.col, row);
|
|
68077
|
-
if (
|
|
68140
|
+
if (filteredValuesSet.has(value)) {
|
|
68078
68141
|
hiddenRows.add(row);
|
|
68079
68142
|
}
|
|
68080
68143
|
}
|
|
@@ -76988,9 +77051,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
76988
77051
|
exports.tokenize = tokenize;
|
|
76989
77052
|
|
|
76990
77053
|
|
|
76991
|
-
__info__.version = "18.2.
|
|
76992
|
-
__info__.date = "2025-06-
|
|
76993
|
-
__info__.hash = "
|
|
77054
|
+
__info__.version = "18.2.18";
|
|
77055
|
+
__info__.date = "2025-06-19T18:24:41.051Z";
|
|
77056
|
+
__info__.hash = "024c134";
|
|
76994
77057
|
|
|
76995
77058
|
|
|
76996
77059
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|