@odoo/o-spreadsheet 17.2.5 → 17.2.7
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.
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
5
5
|
* @see https://github.com/odoo/o-spreadsheet
|
|
6
|
-
* @version 17.2.
|
|
7
|
-
* @date 2024-
|
|
8
|
-
* @hash
|
|
6
|
+
* @version 17.2.7
|
|
7
|
+
* @date 2024-05-15T09:20:44.429Z
|
|
8
|
+
* @hash 57e89fa
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
'use strict';
|
|
@@ -554,7 +554,7 @@ function getAddHeaderStartIndex(position, base) {
|
|
|
554
554
|
/**
|
|
555
555
|
* Compares two objects.
|
|
556
556
|
*/
|
|
557
|
-
function deepEquals(o1, o2) {
|
|
557
|
+
function deepEquals(o1, o2, ignoreFunctions) {
|
|
558
558
|
if (o1 === o2)
|
|
559
559
|
return true;
|
|
560
560
|
if ((o1 && !o2) || (o2 && !o1))
|
|
@@ -570,13 +570,16 @@ function deepEquals(o1, o2) {
|
|
|
570
570
|
}
|
|
571
571
|
}
|
|
572
572
|
for (const key in o1) {
|
|
573
|
-
|
|
573
|
+
const typeOfO1Key = typeof o1[key];
|
|
574
|
+
if (typeOfO1Key !== typeof o2[key])
|
|
574
575
|
return false;
|
|
575
|
-
if (
|
|
576
|
-
if (!deepEquals(o1[key], o2[key]))
|
|
576
|
+
if (typeOfO1Key === "object") {
|
|
577
|
+
if (!deepEquals(o1[key], o2[key], ignoreFunctions))
|
|
577
578
|
return false;
|
|
578
579
|
}
|
|
579
580
|
else {
|
|
581
|
+
if (ignoreFunctions && typeOfO1Key === "function")
|
|
582
|
+
return true;
|
|
580
583
|
if (o1[key] !== o2[key])
|
|
581
584
|
return false;
|
|
582
585
|
}
|
|
@@ -3684,21 +3687,22 @@ function toZoneWithoutBoundaryChanges(xc) {
|
|
|
3684
3687
|
xc = xc.split("!").at(-1);
|
|
3685
3688
|
}
|
|
3686
3689
|
if (xc.includes("$")) {
|
|
3687
|
-
xc = xc.
|
|
3690
|
+
xc = xc.replaceAll("$", "");
|
|
3688
3691
|
}
|
|
3689
|
-
let
|
|
3692
|
+
let firstRangePart = "";
|
|
3693
|
+
let secondRangePart;
|
|
3690
3694
|
if (xc.includes(":")) {
|
|
3691
|
-
|
|
3695
|
+
[firstRangePart, secondRangePart] = xc.split(":");
|
|
3696
|
+
firstRangePart = firstRangePart.trim();
|
|
3697
|
+
secondRangePart = secondRangePart.trim();
|
|
3692
3698
|
}
|
|
3693
3699
|
else {
|
|
3694
|
-
|
|
3700
|
+
firstRangePart = xc.trim();
|
|
3695
3701
|
}
|
|
3696
3702
|
let top, bottom, left, right;
|
|
3697
3703
|
let fullCol = false;
|
|
3698
3704
|
let fullRow = false;
|
|
3699
3705
|
let hasHeader = false;
|
|
3700
|
-
const firstRangePart = ranges[0];
|
|
3701
|
-
const secondRangePart = ranges[1] && ranges[1];
|
|
3702
3706
|
if (isColReference(firstRangePart)) {
|
|
3703
3707
|
left = right = lettersToNumber(firstRangePart);
|
|
3704
3708
|
top = bottom = 0;
|
|
@@ -3715,7 +3719,7 @@ function toZoneWithoutBoundaryChanges(xc) {
|
|
|
3715
3719
|
top = bottom = c.row;
|
|
3716
3720
|
hasHeader = true;
|
|
3717
3721
|
}
|
|
3718
|
-
if (
|
|
3722
|
+
if (secondRangePart) {
|
|
3719
3723
|
if (isColReference(secondRangePart)) {
|
|
3720
3724
|
right = lettersToNumber(secondRangePart);
|
|
3721
3725
|
fullCol = true;
|
|
@@ -5199,7 +5203,7 @@ function tokenizeString(chars) {
|
|
|
5199
5203
|
}
|
|
5200
5204
|
return null;
|
|
5201
5205
|
}
|
|
5202
|
-
const
|
|
5206
|
+
const SYMBOL_CHARS = new Set("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!$");
|
|
5203
5207
|
/**
|
|
5204
5208
|
* A "Symbol" is just basically any word-like element that can appear in a
|
|
5205
5209
|
* formula, which is not a string. So:
|
|
@@ -5239,11 +5243,8 @@ function tokenizeSymbol(chars) {
|
|
|
5239
5243
|
};
|
|
5240
5244
|
}
|
|
5241
5245
|
}
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
const value = match[0];
|
|
5245
|
-
result += value;
|
|
5246
|
-
chars.advanceBy(value.length);
|
|
5246
|
+
while (chars.current && SYMBOL_CHARS.has(chars.current)) {
|
|
5247
|
+
result += chars.shift();
|
|
5247
5248
|
}
|
|
5248
5249
|
if (result.length) {
|
|
5249
5250
|
const value = result;
|
|
@@ -6795,7 +6796,7 @@ const machine = {
|
|
|
6795
6796
|
function matchReference(tokens) {
|
|
6796
6797
|
let head = 0;
|
|
6797
6798
|
let transitions = machine[State.LeftRef];
|
|
6798
|
-
|
|
6799
|
+
let matchedTokens = "";
|
|
6799
6800
|
while (transitions !== undefined) {
|
|
6800
6801
|
const token = tokens[head++];
|
|
6801
6802
|
if (!token) {
|
|
@@ -6807,15 +6808,15 @@ function matchReference(tokens) {
|
|
|
6807
6808
|
case undefined:
|
|
6808
6809
|
return null;
|
|
6809
6810
|
case State.Found:
|
|
6810
|
-
matchedTokens.
|
|
6811
|
+
matchedTokens += token.value;
|
|
6811
6812
|
tokens.splice(0, head);
|
|
6812
6813
|
return {
|
|
6813
6814
|
type: "REFERENCE",
|
|
6814
|
-
value:
|
|
6815
|
+
value: matchedTokens,
|
|
6815
6816
|
};
|
|
6816
6817
|
default:
|
|
6817
6818
|
transitions = machine[nextState];
|
|
6818
|
-
matchedTokens.
|
|
6819
|
+
matchedTokens += token.value;
|
|
6819
6820
|
break;
|
|
6820
6821
|
}
|
|
6821
6822
|
}
|
|
@@ -8906,8 +8907,7 @@ class ComposerStore extends SpreadsheetStore {
|
|
|
8906
8907
|
const exactMatch = proposals?.find((p) => p.text === tokenAtCursor.value);
|
|
8907
8908
|
// remove tokens that are likely to be other parts of the formula that slipped in the token if it's a string
|
|
8908
8909
|
const searchTerm = tokenAtCursor.value.replace(/[ ,\(\)]/g, "");
|
|
8909
|
-
|
|
8910
|
-
if (exactMatch && exactMatch.text !== initialContent) {
|
|
8910
|
+
if (exactMatch && this._currentContent !== this.initialContent) {
|
|
8911
8911
|
// this means the user has chosen a proposal
|
|
8912
8912
|
return;
|
|
8913
8913
|
}
|
|
@@ -8915,7 +8915,7 @@ class ComposerStore extends SpreadsheetStore {
|
|
|
8915
8915
|
proposals &&
|
|
8916
8916
|
!["ARG_SEPARATOR", "LEFT_PAREN"].includes(tokenAtCursor.type)) {
|
|
8917
8917
|
const filteredProposals = fuzzyLookup(searchTerm, proposals, (p) => p.fuzzySearchKey || p.text);
|
|
8918
|
-
if (!exactMatch) {
|
|
8918
|
+
if (!exactMatch || filteredProposals.length > 1) {
|
|
8919
8919
|
proposals = filteredProposals;
|
|
8920
8920
|
}
|
|
8921
8921
|
}
|
|
@@ -9050,6 +9050,7 @@ class ChartJsComponent extends owl.Component {
|
|
|
9050
9050
|
};
|
|
9051
9051
|
canvas = owl.useRef("graphContainer");
|
|
9052
9052
|
chart;
|
|
9053
|
+
currentRuntime;
|
|
9053
9054
|
get background() {
|
|
9054
9055
|
return this.chartRuntime.background;
|
|
9055
9056
|
}
|
|
@@ -9066,9 +9067,18 @@ class ChartJsComponent extends owl.Component {
|
|
|
9066
9067
|
setup() {
|
|
9067
9068
|
owl.onMounted(() => {
|
|
9068
9069
|
const runtime = this.chartRuntime;
|
|
9069
|
-
this.
|
|
9070
|
+
this.currentRuntime = runtime;
|
|
9071
|
+
// Note: chartJS modify the runtime in place, so it's important to give it a copy
|
|
9072
|
+
this.createChart(deepCopy(runtime.chartJsConfig));
|
|
9073
|
+
});
|
|
9074
|
+
owl.onWillUnmount(() => this.chart?.destroy());
|
|
9075
|
+
owl.useEffect(() => {
|
|
9076
|
+
const runtime = this.chartRuntime;
|
|
9077
|
+
if (!deepEquals(runtime, this.currentRuntime, "ignoreFunctions")) {
|
|
9078
|
+
this.currentRuntime = runtime;
|
|
9079
|
+
this.updateChartJs(deepCopy(runtime));
|
|
9080
|
+
}
|
|
9070
9081
|
});
|
|
9071
|
-
owl.useEffect(() => this.updateChartJs(this.chartRuntime), () => [this.chartRuntime]);
|
|
9072
9082
|
}
|
|
9073
9083
|
createChart(chartData) {
|
|
9074
9084
|
const canvas = this.canvas.el;
|
|
@@ -9090,8 +9100,7 @@ class ChartJsComponent extends owl.Component {
|
|
|
9090
9100
|
this.chart.config.options.plugins.tooltip = chartData.options.plugins.tooltip;
|
|
9091
9101
|
this.chart.config.options.plugins.legend = chartData.options.plugins.legend;
|
|
9092
9102
|
this.chart.config.options.scales = chartData.options?.scales;
|
|
9093
|
-
|
|
9094
|
-
this.chart.update("active");
|
|
9103
|
+
this.chart.update();
|
|
9095
9104
|
}
|
|
9096
9105
|
}
|
|
9097
9106
|
|
|
@@ -19454,7 +19463,7 @@ function truncateLabel(label) {
|
|
|
19454
19463
|
/**
|
|
19455
19464
|
* Get a default chart js configuration
|
|
19456
19465
|
*/
|
|
19457
|
-
function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale }) {
|
|
19466
|
+
function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, truncateLabels }) {
|
|
19458
19467
|
const options = {
|
|
19459
19468
|
// https://www.chartjs.org/docs/latest/general/responsive.html
|
|
19460
19469
|
responsive: true,
|
|
@@ -19501,7 +19510,7 @@ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale })
|
|
|
19501
19510
|
type: chart.type,
|
|
19502
19511
|
options,
|
|
19503
19512
|
data: {
|
|
19504
|
-
labels: labels.map(truncateLabel),
|
|
19513
|
+
labels: truncateLabels ? labels.map(truncateLabel) : labels,
|
|
19505
19514
|
datasets: [],
|
|
19506
19515
|
},
|
|
19507
19516
|
platform: undefined,
|
|
@@ -20267,9 +20276,9 @@ function isLuxonTimeAdapterInstalled() {
|
|
|
20267
20276
|
}
|
|
20268
20277
|
return isInstalled;
|
|
20269
20278
|
}
|
|
20270
|
-
function getLineOrScatterConfiguration(chart, labels,
|
|
20279
|
+
function getLineOrScatterConfiguration(chart, labels, options) {
|
|
20271
20280
|
const fontColor = chartFontColor(chart.background);
|
|
20272
|
-
const config = getDefaultChartJsRuntime(chart, labels, fontColor,
|
|
20281
|
+
const config = getDefaultChartJsRuntime(chart, labels, fontColor, options);
|
|
20273
20282
|
const legend = {
|
|
20274
20283
|
labels: {
|
|
20275
20284
|
color: fontColor,
|
|
@@ -20312,7 +20321,7 @@ function getLineOrScatterConfiguration(chart, labels, localeFormat) {
|
|
|
20312
20321
|
value = Number(value);
|
|
20313
20322
|
if (isNaN(value))
|
|
20314
20323
|
return value;
|
|
20315
|
-
const { locale, format } =
|
|
20324
|
+
const { locale, format } = options;
|
|
20316
20325
|
return formatValue(value, {
|
|
20317
20326
|
locale,
|
|
20318
20327
|
format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
|
|
@@ -20345,9 +20354,10 @@ function createLineOrScatterChartRuntime(chart, getters) {
|
|
|
20345
20354
|
({ labels, dataSetsValues } = aggregateDataForLabels(labels, dataSetsValues));
|
|
20346
20355
|
}
|
|
20347
20356
|
const locale = getters.getLocale();
|
|
20357
|
+
const truncateLabels = axisType === "category";
|
|
20348
20358
|
const dataSetFormat = getChartDatasetFormat(getters, chart.dataSets);
|
|
20349
|
-
const
|
|
20350
|
-
const config = getLineOrScatterConfiguration(chart, labels,
|
|
20359
|
+
const options = { format: dataSetFormat, locale, truncateLabels };
|
|
20360
|
+
const config = getLineOrScatterConfiguration(chart, labels, options);
|
|
20351
20361
|
const labelFormat = getChartLabelFormat(getters, chart.labelRange);
|
|
20352
20362
|
if (axisType === "time") {
|
|
20353
20363
|
const axis = {
|
|
@@ -32901,7 +32911,8 @@ class DataValidationOverlay extends owl.Component {
|
|
|
32901
32911
|
get checkBoxCellPositions() {
|
|
32902
32912
|
return this.env.model.getters
|
|
32903
32913
|
.getVisibleCellPositions()
|
|
32904
|
-
.filter(this.env.model.getters.isCellValidCheckbox)
|
|
32914
|
+
.filter((position) => this.env.model.getters.isCellValidCheckbox(position) &&
|
|
32915
|
+
!this.env.model.getters.isFilterHeader(position));
|
|
32905
32916
|
}
|
|
32906
32917
|
get listIconsCellPositions() {
|
|
32907
32918
|
if (this.env.model.getters.isReadonly()) {
|
|
@@ -32909,7 +32920,8 @@ class DataValidationOverlay extends owl.Component {
|
|
|
32909
32920
|
}
|
|
32910
32921
|
return this.env.model.getters
|
|
32911
32922
|
.getVisibleCellPositions()
|
|
32912
|
-
.filter(this.env.model.getters.cellHasListDataValidationIcon)
|
|
32923
|
+
.filter((position) => this.env.model.getters.cellHasListDataValidationIcon(position) &&
|
|
32924
|
+
!this.env.model.getters.isFilterHeader(position));
|
|
32913
32925
|
}
|
|
32914
32926
|
}
|
|
32915
32927
|
|
|
@@ -47422,9 +47434,10 @@ class Evaluator {
|
|
|
47422
47434
|
}
|
|
47423
47435
|
if (!content) {
|
|
47424
47436
|
// The previous content could have blocked some array formulas
|
|
47425
|
-
impactedPositions.
|
|
47437
|
+
impactedPositions.add(position);
|
|
47426
47438
|
}
|
|
47427
47439
|
}
|
|
47440
|
+
impactedPositions.addMany(this.getArrayFormulasBlockedBy(impactedPositions));
|
|
47428
47441
|
return impactedPositions;
|
|
47429
47442
|
}
|
|
47430
47443
|
buildDependencyGraph() {
|
|
@@ -47466,23 +47479,25 @@ class Evaluator {
|
|
|
47466
47479
|
return positions;
|
|
47467
47480
|
}
|
|
47468
47481
|
/**
|
|
47469
|
-
* Return the position of formulas blocked by the given
|
|
47482
|
+
* Return the position of formulas blocked by the given positions
|
|
47470
47483
|
* as well as all their dependencies.
|
|
47471
47484
|
*/
|
|
47472
|
-
getArrayFormulasBlockedBy(
|
|
47473
|
-
|
|
47474
|
-
|
|
47475
|
-
|
|
47476
|
-
|
|
47477
|
-
|
|
47478
|
-
|
|
47479
|
-
|
|
47480
|
-
|
|
47481
|
-
|
|
47482
|
-
|
|
47485
|
+
getArrayFormulasBlockedBy(positions) {
|
|
47486
|
+
const arrayFormulaPositions = this.createEmptyPositionSet();
|
|
47487
|
+
for (const position of positions) {
|
|
47488
|
+
if (!this.spreadingRelations.hasArrayFormulaResult(position)) {
|
|
47489
|
+
continue;
|
|
47490
|
+
}
|
|
47491
|
+
const arrayFormulas = this.spreadingRelations.getFormulaPositionsSpreadingOn(position);
|
|
47492
|
+
arrayFormulaPositions.addMany(arrayFormulas);
|
|
47493
|
+
const arrayFormulaPosition = this.getArrayFormulaSpreadingOn(position);
|
|
47494
|
+
if (arrayFormulaPosition) {
|
|
47495
|
+
// ignore the formula spreading on the position. Keep only the blocked ones
|
|
47496
|
+
arrayFormulaPositions.delete(arrayFormulaPosition);
|
|
47497
|
+
}
|
|
47483
47498
|
}
|
|
47484
|
-
|
|
47485
|
-
return
|
|
47499
|
+
arrayFormulaPositions.addMany(this.getCellsDependingOn(arrayFormulaPositions));
|
|
47500
|
+
return arrayFormulaPositions;
|
|
47486
47501
|
}
|
|
47487
47502
|
nextPositionsToUpdate = new PositionSet({});
|
|
47488
47503
|
cellsBeingComputed = new Set();
|
|
@@ -47612,6 +47627,7 @@ class Evaluator {
|
|
|
47612
47627
|
if (!this.spreadingRelations.isArrayFormula(position)) {
|
|
47613
47628
|
return;
|
|
47614
47629
|
}
|
|
47630
|
+
const invalidated = this.createEmptyPositionSet();
|
|
47615
47631
|
for (const child of this.spreadingRelations.getArrayResultPositions(position)) {
|
|
47616
47632
|
const content = this.getters.getCell(child)?.content;
|
|
47617
47633
|
if (content) {
|
|
@@ -47619,10 +47635,11 @@ class Evaluator {
|
|
|
47619
47635
|
// there's still a collision
|
|
47620
47636
|
continue;
|
|
47621
47637
|
}
|
|
47638
|
+
invalidated.add(child);
|
|
47622
47639
|
this.evaluatedCells.delete(child);
|
|
47623
|
-
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([child]));
|
|
47624
|
-
this.nextPositionsToUpdate.addMany(this.getArrayFormulasBlockedBy(child));
|
|
47625
47640
|
}
|
|
47641
|
+
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn(invalidated));
|
|
47642
|
+
this.nextPositionsToUpdate.addMany(this.getArrayFormulasBlockedBy(invalidated));
|
|
47626
47643
|
this.spreadingRelations.removeNode(position);
|
|
47627
47644
|
}
|
|
47628
47645
|
// ----------------------------------------------------------
|
|
@@ -47929,7 +47946,7 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
47929
47946
|
? getItemId(newFormat, data.formats)
|
|
47930
47947
|
: exportedCellData.format;
|
|
47931
47948
|
let content;
|
|
47932
|
-
if (isFormula && formulaCell instanceof FormulaCellWithDependencies) {
|
|
47949
|
+
if (isExported && isFormula && formulaCell instanceof FormulaCellWithDependencies) {
|
|
47933
47950
|
content = formulaCell.contentWithFixedReferences;
|
|
47934
47951
|
}
|
|
47935
47952
|
else {
|
|
@@ -60600,6 +60617,6 @@ exports.tokenColors = tokenColors;
|
|
|
60600
60617
|
exports.tokenize = tokenize;
|
|
60601
60618
|
|
|
60602
60619
|
|
|
60603
|
-
__info__.version = "17.2.
|
|
60604
|
-
__info__.date = "2024-
|
|
60605
|
-
__info__.hash = "
|
|
60620
|
+
__info__.version = "17.2.7";
|
|
60621
|
+
__info__.date = "2024-05-15T09:20:44.429Z";
|
|
60622
|
+
__info__.hash = "57e89fa";
|
package/dist/o-spreadsheet.d.ts
CHANGED
|
@@ -4937,7 +4937,7 @@ declare function lazy<T>(fn: (() => T) | T): Lazy<T>;
|
|
|
4937
4937
|
/**
|
|
4938
4938
|
* Compares two objects.
|
|
4939
4939
|
*/
|
|
4940
|
-
declare function deepEquals(o1: any, o2: any): boolean;
|
|
4940
|
+
declare function deepEquals(o1: any, o2: any, ignoreFunctions?: "ignoreFunctions"): boolean;
|
|
4941
4941
|
|
|
4942
4942
|
interface ConstructorArgs {
|
|
4943
4943
|
readonly zone: Readonly<Zone | UnboundedZone>;
|
|
@@ -6858,6 +6858,7 @@ declare class ChartJsComponent extends Component<Props$y, SpreadsheetChildEnv> {
|
|
|
6858
6858
|
};
|
|
6859
6859
|
private canvas;
|
|
6860
6860
|
private chart?;
|
|
6861
|
+
private currentRuntime;
|
|
6861
6862
|
get background(): string;
|
|
6862
6863
|
get canvasStyle(): string;
|
|
6863
6864
|
get chartRuntime(): ChartJSRuntime;
|
|
@@ -8028,7 +8029,9 @@ declare function chartFontColor(backgroundColor: Color | undefined): Color;
|
|
|
8028
8029
|
/**
|
|
8029
8030
|
* Get a default chart js configuration
|
|
8030
8031
|
*/
|
|
8031
|
-
declare function getDefaultChartJsRuntime(chart: AbstractChart, labels: string[], fontColor: Color, { format, locale }: LocaleFormat
|
|
8032
|
+
declare function getDefaultChartJsRuntime(chart: AbstractChart, labels: string[], fontColor: Color, { format, locale, truncateLabels }: LocaleFormat & {
|
|
8033
|
+
truncateLabels?: boolean;
|
|
8034
|
+
}): Required<ChartConfiguration>;
|
|
8032
8035
|
/** See https://www.chartjs.org/docs/latest/charts/area.html#filling-modes */
|
|
8033
8036
|
declare function getFillingMode(index: number): "origin" | number;
|
|
8034
8037
|
|