@odoo/o-spreadsheet 18.0.50 → 18.0.54
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 +194 -121
- package/dist/o-spreadsheet.d.ts +14 -5
- package/dist/o-spreadsheet.esm.js +194 -121
- package/dist/o-spreadsheet.iife.js +194 -121
- package/dist/o-spreadsheet.iife.min.js +151 -162
- package/dist/o_spreadsheet.xml +33 -35
- 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.0.
|
|
6
|
-
* @date
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.0.54
|
|
6
|
+
* @date 2026-01-14T10:00:02.287Z
|
|
7
|
+
* @hash c0048a0
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -5840,17 +5840,41 @@ function toCriterionDateNumber(dateValue) {
|
|
|
5840
5840
|
const today = DateTime.now();
|
|
5841
5841
|
switch (dateValue) {
|
|
5842
5842
|
case "today":
|
|
5843
|
-
return jsDateToNumber(today);
|
|
5844
|
-
case "yesterday":
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
|
|
5843
|
+
return Math.floor(jsDateToNumber(today));
|
|
5844
|
+
case "yesterday": {
|
|
5845
|
+
today.setDate(today.getDate() - 1);
|
|
5846
|
+
return Math.floor(jsDateToNumber(today));
|
|
5847
|
+
}
|
|
5848
|
+
case "tomorrow": {
|
|
5849
|
+
today.setDate(today.getDate() + 1);
|
|
5850
|
+
return Math.floor(jsDateToNumber(today));
|
|
5851
|
+
}
|
|
5848
5852
|
case "lastWeek":
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5853
|
+
today.setDate(today.getDate() - 6);
|
|
5854
|
+
return Math.floor(jsDateToNumber(today));
|
|
5855
|
+
case "lastMonth": {
|
|
5856
|
+
const lastMonth = today.getMonth() === 0 ? 11 : today.getMonth() - 1;
|
|
5857
|
+
const dateInLastMonth = new DateTime(today.getFullYear(), lastMonth, 1);
|
|
5858
|
+
if (today.getDate() > getDaysInMonth(dateInLastMonth)) {
|
|
5859
|
+
today.setDate(1);
|
|
5860
|
+
}
|
|
5861
|
+
else {
|
|
5862
|
+
today.setDate(today.getDate() + 1);
|
|
5863
|
+
today.setMonth(today.getMonth() - 1);
|
|
5864
|
+
}
|
|
5865
|
+
return Math.floor(jsDateToNumber(today));
|
|
5866
|
+
}
|
|
5852
5867
|
case "lastYear":
|
|
5853
|
-
|
|
5868
|
+
// Handle leap year case
|
|
5869
|
+
if (today.getMonth() === 1 && today.getDate() === 29) {
|
|
5870
|
+
today.setDate(28);
|
|
5871
|
+
today.setFullYear(today.getFullYear() - 1);
|
|
5872
|
+
}
|
|
5873
|
+
else {
|
|
5874
|
+
today.setDate(today.getDate() + 1);
|
|
5875
|
+
today.setFullYear(today.getFullYear() - 1);
|
|
5876
|
+
}
|
|
5877
|
+
return Math.floor(jsDateToNumber(today));
|
|
5854
5878
|
}
|
|
5855
5879
|
}
|
|
5856
5880
|
/** Get all the dates values of a criterion converted to numbers, converting date values such as "today" to actual dates */
|
|
@@ -18541,9 +18565,10 @@ function assertDomainLength(domain) {
|
|
|
18541
18565
|
throw new EvaluationError(_t("Function PIVOT takes an even number of arguments."));
|
|
18542
18566
|
}
|
|
18543
18567
|
}
|
|
18544
|
-
function addPivotDependencies(evalContext,
|
|
18568
|
+
function addPivotDependencies(evalContext, pivotId, forMeasures) {
|
|
18545
18569
|
//TODO This function can be very costly when used with PIVOT.VALUE and PIVOT.HEADER
|
|
18546
18570
|
const dependencies = [];
|
|
18571
|
+
const coreDefinition = evalContext.getters.getPivotCoreDefinition(pivotId);
|
|
18547
18572
|
if (coreDefinition.type === "SPREADSHEET" && coreDefinition.dataSet) {
|
|
18548
18573
|
const { sheetId, zone } = coreDefinition.dataSet;
|
|
18549
18574
|
const xc = zoneToXc(zone);
|
|
@@ -18560,8 +18585,7 @@ function addPivotDependencies(evalContext, coreDefinition, forMeasures) {
|
|
|
18560
18585
|
}
|
|
18561
18586
|
for (const measure of forMeasures) {
|
|
18562
18587
|
if (measure.computedBy) {
|
|
18563
|
-
|
|
18564
|
-
dependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
|
|
18588
|
+
dependencies.push(...evalContext.getters.getMeasureFullDependencies(pivotId, measure));
|
|
18565
18589
|
}
|
|
18566
18590
|
}
|
|
18567
18591
|
const originPosition = evalContext.__originCellPosition;
|
|
@@ -19002,7 +19026,7 @@ const PIVOT_VALUE = {
|
|
|
19002
19026
|
assertDomainLength(domainArgs);
|
|
19003
19027
|
const pivot = this.getters.getPivot(pivotId);
|
|
19004
19028
|
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
19005
|
-
addPivotDependencies(this,
|
|
19029
|
+
addPivotDependencies(this, pivotId, coreDefinition.measures.filter((m) => m.id === _measure));
|
|
19006
19030
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
19007
19031
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
19008
19032
|
if (error) {
|
|
@@ -19035,8 +19059,7 @@ const PIVOT_HEADER = {
|
|
|
19035
19059
|
const _pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
19036
19060
|
assertDomainLength(domainArgs);
|
|
19037
19061
|
const pivot = this.getters.getPivot(_pivotId);
|
|
19038
|
-
|
|
19039
|
-
addPivotDependencies(this, coreDefinition, []);
|
|
19062
|
+
addPivotDependencies(this, _pivotId, []);
|
|
19040
19063
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
19041
19064
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
19042
19065
|
if (error) {
|
|
@@ -19090,7 +19113,7 @@ const PIVOT = {
|
|
|
19090
19113
|
const pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
19091
19114
|
const pivot = this.getters.getPivot(pivotId);
|
|
19092
19115
|
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
19093
|
-
addPivotDependencies(this,
|
|
19116
|
+
addPivotDependencies(this, pivotId, coreDefinition.measures);
|
|
19094
19117
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
19095
19118
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
19096
19119
|
if (error) {
|
|
@@ -40347,14 +40370,15 @@ function useHighlights(highlightProvider) {
|
|
|
40347
40370
|
}
|
|
40348
40371
|
|
|
40349
40372
|
css /* scss */ `
|
|
40350
|
-
.o-cf-preview {
|
|
40373
|
+
.o-spreadsheet .o-cf-preview {
|
|
40351
40374
|
&.o-cf-cursor-ptr {
|
|
40352
40375
|
cursor: pointer;
|
|
40353
40376
|
}
|
|
40354
40377
|
|
|
40355
40378
|
border-bottom: 1px solid ${GRAY_300};
|
|
40356
|
-
height:
|
|
40379
|
+
height: 80px;
|
|
40357
40380
|
padding: 10px;
|
|
40381
|
+
box-sizing: border-box;
|
|
40358
40382
|
position: relative;
|
|
40359
40383
|
cursor: pointer;
|
|
40360
40384
|
&:hover,
|
|
@@ -40368,7 +40392,6 @@ css /* scss */ `
|
|
|
40368
40392
|
.o-cf-preview-icon {
|
|
40369
40393
|
border: 1px solid ${GRAY_300};
|
|
40370
40394
|
background-color: #fff;
|
|
40371
|
-
position: absolute;
|
|
40372
40395
|
height: 50px;
|
|
40373
40396
|
width: 50px;
|
|
40374
40397
|
.o-icon {
|
|
@@ -40377,12 +40400,6 @@ css /* scss */ `
|
|
|
40377
40400
|
}
|
|
40378
40401
|
}
|
|
40379
40402
|
.o-cf-preview-description {
|
|
40380
|
-
left: 65px;
|
|
40381
|
-
margin-bottom: auto;
|
|
40382
|
-
margin-right: 8px;
|
|
40383
|
-
margin-top: auto;
|
|
40384
|
-
position: relative;
|
|
40385
|
-
width: 142px;
|
|
40386
40403
|
.o-cf-preview-description-rule {
|
|
40387
40404
|
margin-bottom: 4px;
|
|
40388
40405
|
max-height: 2.8em;
|
|
@@ -40392,16 +40409,11 @@ css /* scss */ `
|
|
|
40392
40409
|
font-size: 12px;
|
|
40393
40410
|
}
|
|
40394
40411
|
}
|
|
40395
|
-
.o-cf-delete {
|
|
40396
|
-
left: 90%;
|
|
40397
|
-
top: 39%;
|
|
40398
|
-
position: absolute;
|
|
40399
|
-
}
|
|
40400
40412
|
&:not(:hover):not(.o-cf-dragging) .o-cf-drag-handle {
|
|
40401
40413
|
display: none !important;
|
|
40402
40414
|
}
|
|
40403
40415
|
.o-cf-drag-handle {
|
|
40404
|
-
left:
|
|
40416
|
+
left: 2px;
|
|
40405
40417
|
cursor: move;
|
|
40406
40418
|
.o-icon {
|
|
40407
40419
|
width: 6px;
|
|
@@ -41286,7 +41298,7 @@ dataValidationEvaluatorRegistry.add("dateIs", {
|
|
|
41286
41298
|
return false;
|
|
41287
41299
|
}
|
|
41288
41300
|
if (["lastWeek", "lastMonth", "lastYear"].includes(criterion.dateValue)) {
|
|
41289
|
-
const today =
|
|
41301
|
+
const today = Math.floor(jsDateToNumber(DateTime.now()));
|
|
41290
41302
|
return isDateBetween(dateValue, today, criterionValue);
|
|
41291
41303
|
}
|
|
41292
41304
|
return areDatesSameDay(dateValue, criterionValue);
|
|
@@ -42448,6 +42460,11 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
42448
42460
|
case "UPDATE_CELL":
|
|
42449
42461
|
case "ACTIVATE_SHEET":
|
|
42450
42462
|
this.isSearchDirty = true;
|
|
42463
|
+
if (this.searchOptions.specificRange) {
|
|
42464
|
+
this.searchOptions.specificRange = this.searchOptions.specificRange.clone({
|
|
42465
|
+
sheetId: this.getters.getActiveSheetId(),
|
|
42466
|
+
});
|
|
42467
|
+
}
|
|
42451
42468
|
break;
|
|
42452
42469
|
case "REPLACE_SEARCH":
|
|
42453
42470
|
for (const match of cmd.matches) {
|
|
@@ -42853,9 +42870,20 @@ class FindAndReplacePanel extends owl.Component {
|
|
|
42853
42870
|
const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.dataRange);
|
|
42854
42871
|
this.store.updateSearchOptions({ specificRange });
|
|
42855
42872
|
}
|
|
42873
|
+
get specificRange() {
|
|
42874
|
+
const range = this.store.searchOptions.specificRange;
|
|
42875
|
+
return range ? this.env.model.getters.getRangeString(range, "forceSheetReference") : "";
|
|
42876
|
+
}
|
|
42856
42877
|
get pendingSearch() {
|
|
42857
42878
|
return this.updateSearchContent.isDebouncePending();
|
|
42858
42879
|
}
|
|
42880
|
+
get selectionInputKey() {
|
|
42881
|
+
// Selections input are made to work with objects linked to a sheet id. They store the active sheet id at their creation,
|
|
42882
|
+
// and have specific behaviour linked to it (eg. go back to the initial sheet after confirmation).
|
|
42883
|
+
// We don't want all those behaviors here, so we force the recreation of the component when the active sheet changes.
|
|
42884
|
+
// The only drawback is that the input loses focus when changing sheet.
|
|
42885
|
+
return this.env.model.getters.getActiveSheetId();
|
|
42886
|
+
}
|
|
42859
42887
|
}
|
|
42860
42888
|
|
|
42861
42889
|
css /* scss */ `
|
|
@@ -44990,7 +45018,37 @@ pivotRegistry.add("SPREADSHEET", {
|
|
|
44990
45018
|
datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
|
|
44991
45019
|
isMeasureCandidate: (field) => !["datetime", "boolean"].includes(field.type),
|
|
44992
45020
|
isGroupable: () => true,
|
|
45021
|
+
adaptRanges: (getters, definition, applyChange) => {
|
|
45022
|
+
if (definition.type !== "SPREADSHEET" || !definition.dataSet) {
|
|
45023
|
+
return definition;
|
|
45024
|
+
}
|
|
45025
|
+
const { sheetId, zone } = definition.dataSet;
|
|
45026
|
+
const range = getters.getRangeFromZone(sheetId, zone);
|
|
45027
|
+
const adaptedRange = adaptPivotRange(range, applyChange);
|
|
45028
|
+
if (adaptedRange === range) {
|
|
45029
|
+
return definition;
|
|
45030
|
+
}
|
|
45031
|
+
const dataSet = adaptedRange && {
|
|
45032
|
+
sheetId: adaptedRange.sheetId,
|
|
45033
|
+
zone: adaptedRange.zone,
|
|
45034
|
+
};
|
|
45035
|
+
return { ...definition, dataSet };
|
|
45036
|
+
},
|
|
44993
45037
|
});
|
|
45038
|
+
function adaptPivotRange(range, applyChange) {
|
|
45039
|
+
if (!range) {
|
|
45040
|
+
return undefined;
|
|
45041
|
+
}
|
|
45042
|
+
const change = applyChange(range);
|
|
45043
|
+
switch (change.changeType) {
|
|
45044
|
+
case "NONE":
|
|
45045
|
+
return range;
|
|
45046
|
+
case "REMOVE":
|
|
45047
|
+
return undefined;
|
|
45048
|
+
default:
|
|
45049
|
+
return change.range;
|
|
45050
|
+
}
|
|
45051
|
+
}
|
|
44994
45052
|
|
|
44995
45053
|
class PivotSidePanelStore extends SpreadsheetStore {
|
|
44996
45054
|
pivotId;
|
|
@@ -46877,21 +46935,20 @@ class ArrayFormulaHighlight extends SpreadsheetStore {
|
|
|
46877
46935
|
this.highlightStore.register(this);
|
|
46878
46936
|
}
|
|
46879
46937
|
get highlights() {
|
|
46880
|
-
let zone;
|
|
46881
46938
|
const position = this.model.getters.getActivePosition();
|
|
46882
|
-
const cell = this.getters.getEvaluatedCell(position);
|
|
46883
46939
|
const spreader = this.model.getters.getArrayFormulaSpreadingOn(position);
|
|
46884
|
-
zone = spreader
|
|
46940
|
+
const zone = spreader
|
|
46885
46941
|
? this.model.getters.getSpreadZone(spreader, { ignoreSpillError: true })
|
|
46886
46942
|
: this.model.getters.getSpreadZone(position, { ignoreSpillError: true });
|
|
46887
46943
|
if (!zone) {
|
|
46888
46944
|
return [];
|
|
46889
46945
|
}
|
|
46946
|
+
const isArrayFormulaBlocked = this.model.getters.isArrayFormulaSpillBlocked(spreader ?? position);
|
|
46890
46947
|
return [
|
|
46891
46948
|
{
|
|
46892
46949
|
sheetId: position.sheetId,
|
|
46893
46950
|
zone,
|
|
46894
|
-
dashed:
|
|
46951
|
+
dashed: isArrayFormulaBlocked,
|
|
46895
46952
|
color: "#17A2B8",
|
|
46896
46953
|
noFill: true,
|
|
46897
46954
|
thinLine: true,
|
|
@@ -54952,6 +55009,7 @@ function rangeToMerge(mergeId, range) {
|
|
|
54952
55009
|
class RangeAdapter {
|
|
54953
55010
|
getters;
|
|
54954
55011
|
providers = [];
|
|
55012
|
+
isAdaptingRanges = false;
|
|
54955
55013
|
constructor(getters) {
|
|
54956
55014
|
this.getters = getters;
|
|
54957
55015
|
}
|
|
@@ -54980,6 +55038,9 @@ class RangeAdapter {
|
|
|
54980
55038
|
}
|
|
54981
55039
|
beforeHandle(command) { }
|
|
54982
55040
|
handle(cmd) {
|
|
55041
|
+
if (this.isAdaptingRanges) {
|
|
55042
|
+
throw new Error("Plugins cannot dispatch commands during adaptRanges phase");
|
|
55043
|
+
}
|
|
54983
55044
|
switch (cmd.type) {
|
|
54984
55045
|
case "REMOVE_COLUMNS_ROWS": {
|
|
54985
55046
|
let start = cmd.dimension === "COL" ? "left" : "top";
|
|
@@ -55135,10 +55196,12 @@ class RangeAdapter {
|
|
|
55135
55196
|
return adaptedRange;
|
|
55136
55197
|
}
|
|
55137
55198
|
executeOnAllRanges(adaptRange, sheetId) {
|
|
55199
|
+
this.isAdaptingRanges = true;
|
|
55138
55200
|
const func = this.verifyRangeRemoved(adaptRange);
|
|
55139
55201
|
for (const provider of this.providers) {
|
|
55140
55202
|
provider(func, sheetId);
|
|
55141
55203
|
}
|
|
55204
|
+
this.isAdaptingRanges = false;
|
|
55142
55205
|
}
|
|
55143
55206
|
/**
|
|
55144
55207
|
* Stores the functions bound to each plugin to be able to iterate over all ranges of the application,
|
|
@@ -57157,6 +57220,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
57157
57220
|
"getMeasureCompiledFormula",
|
|
57158
57221
|
"getPivotName",
|
|
57159
57222
|
"isExistingPivot",
|
|
57223
|
+
"getMeasureFullDependencies",
|
|
57160
57224
|
];
|
|
57161
57225
|
nextFormulaId = 1;
|
|
57162
57226
|
pivots = {};
|
|
@@ -57239,15 +57303,32 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
57239
57303
|
}
|
|
57240
57304
|
case "UPDATE_PIVOT": {
|
|
57241
57305
|
this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
|
|
57242
|
-
this.compileCalculatedMeasures(cmd.pivot.measures);
|
|
57306
|
+
this.compileCalculatedMeasures(cmd.pivotId, cmd.pivot.measures);
|
|
57243
57307
|
break;
|
|
57244
57308
|
}
|
|
57245
57309
|
}
|
|
57246
57310
|
}
|
|
57247
57311
|
adaptRanges(applyChange) {
|
|
57248
|
-
for (const
|
|
57249
|
-
|
|
57250
|
-
|
|
57312
|
+
for (const pivotId in this.pivots) {
|
|
57313
|
+
const definition = deepCopy(this.pivots[pivotId]?.definition);
|
|
57314
|
+
if (!definition) {
|
|
57315
|
+
continue;
|
|
57316
|
+
}
|
|
57317
|
+
const newDefinition = pivotRegistry
|
|
57318
|
+
.get(definition.type)
|
|
57319
|
+
?.adaptRanges?.(this.getters, definition, applyChange);
|
|
57320
|
+
if (newDefinition && !deepEquals(definition, newDefinition)) {
|
|
57321
|
+
this.history.update("pivots", pivotId, "definition", newDefinition);
|
|
57322
|
+
}
|
|
57323
|
+
}
|
|
57324
|
+
for (const pivotId in this.compiledMeasureFormulas) {
|
|
57325
|
+
for (const measureId in this.compiledMeasureFormulas[pivotId]) {
|
|
57326
|
+
const measure = this.pivots[pivotId]?.definition.measures.find((m) => m.id === measureId);
|
|
57327
|
+
if (!measure || !measure.computedBy) {
|
|
57328
|
+
continue;
|
|
57329
|
+
}
|
|
57330
|
+
const sheetId = measure.computedBy.sheetId;
|
|
57331
|
+
const compiledFormula = this.compiledMeasureFormulas[pivotId][measureId].formula;
|
|
57251
57332
|
const newDependencies = [];
|
|
57252
57333
|
for (const range of compiledFormula.dependencies) {
|
|
57253
57334
|
const change = applyChange(range);
|
|
@@ -57259,8 +57340,9 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
57259
57340
|
}
|
|
57260
57341
|
}
|
|
57261
57342
|
const newFormulaString = this.getters.getFormulaString(sheetId, compiledFormula.tokens, newDependencies);
|
|
57262
|
-
|
|
57263
|
-
|
|
57343
|
+
const oldFormulaString = measure.computedBy.formula;
|
|
57344
|
+
if (newFormulaString !== oldFormulaString) {
|
|
57345
|
+
this.replaceMeasureFormula(pivotId, measure, newFormulaString);
|
|
57264
57346
|
}
|
|
57265
57347
|
}
|
|
57266
57348
|
}
|
|
@@ -57298,31 +57380,60 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
57298
57380
|
isExistingPivot(pivotId) {
|
|
57299
57381
|
return pivotId in this.pivots;
|
|
57300
57382
|
}
|
|
57301
|
-
getMeasureCompiledFormula(measure) {
|
|
57383
|
+
getMeasureCompiledFormula(pivotId, measure) {
|
|
57384
|
+
if (!measure.computedBy) {
|
|
57385
|
+
throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
|
|
57386
|
+
}
|
|
57387
|
+
return this.compiledMeasureFormulas[pivotId][measure.id].formula;
|
|
57388
|
+
}
|
|
57389
|
+
getMeasureFullDependencies(pivotId, measure) {
|
|
57302
57390
|
if (!measure.computedBy) {
|
|
57303
57391
|
throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
|
|
57304
57392
|
}
|
|
57305
|
-
|
|
57306
|
-
return this.compiledMeasureFormulas[sheetId][measure.computedBy.formula];
|
|
57393
|
+
return this.compiledMeasureFormulas[pivotId][measure.id].dependencies;
|
|
57307
57394
|
}
|
|
57308
57395
|
// -------------------------------------------------------------------------
|
|
57309
57396
|
// Private
|
|
57310
57397
|
// -------------------------------------------------------------------------
|
|
57311
57398
|
addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
|
|
57312
57399
|
this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
|
|
57313
|
-
this.compileCalculatedMeasures(pivot.measures);
|
|
57400
|
+
this.compileCalculatedMeasures(pivotId, pivot.measures);
|
|
57314
57401
|
this.history.update("formulaIds", formulaId, pivotId);
|
|
57315
57402
|
this.history.update("nextFormulaId", this.nextFormulaId + 1);
|
|
57316
57403
|
}
|
|
57317
|
-
compileCalculatedMeasures(measures) {
|
|
57404
|
+
compileCalculatedMeasures(pivotId, measures) {
|
|
57318
57405
|
for (const measure of measures) {
|
|
57319
57406
|
if (measure.computedBy) {
|
|
57320
|
-
const sheetId = measure.computedBy.sheetId;
|
|
57321
57407
|
const compiledFormula = this.compileMeasureFormula(measure.computedBy.sheetId, measure.computedBy.formula);
|
|
57322
|
-
this.history.update("compiledMeasureFormulas",
|
|
57408
|
+
this.history.update("compiledMeasureFormulas", pivotId, measure.id, "formula", compiledFormula);
|
|
57409
|
+
}
|
|
57410
|
+
}
|
|
57411
|
+
for (const measure of measures) {
|
|
57412
|
+
if (measure.computedBy) {
|
|
57413
|
+
const dependencies = this.computeMeasureFullDependencies(pivotId, measure);
|
|
57414
|
+
this.history.update("compiledMeasureFormulas", pivotId, measure.id, "dependencies", dependencies);
|
|
57323
57415
|
}
|
|
57324
57416
|
}
|
|
57325
57417
|
}
|
|
57418
|
+
computeMeasureFullDependencies(pivotId, measure, exploredMeasures = new Set()) {
|
|
57419
|
+
const rangeDependencies = [];
|
|
57420
|
+
const definition = this.getPivotCoreDefinition(pivotId);
|
|
57421
|
+
const formula = this.getMeasureCompiledFormula(pivotId, measure);
|
|
57422
|
+
exploredMeasures.add(measure.id);
|
|
57423
|
+
for (const token of formula.tokens) {
|
|
57424
|
+
if (token.type !== "SYMBOL") {
|
|
57425
|
+
continue;
|
|
57426
|
+
}
|
|
57427
|
+
const otherMeasure = definition.measures.find((measureCandidate) => getCanonicalSymbolName(measureCandidate.id) === token.value &&
|
|
57428
|
+
measure.id !== measureCandidate.id);
|
|
57429
|
+
if (!otherMeasure || exploredMeasures.has(otherMeasure.id) || !otherMeasure.computedBy) {
|
|
57430
|
+
continue;
|
|
57431
|
+
}
|
|
57432
|
+
rangeDependencies.push(...this.computeMeasureFullDependencies(pivotId, otherMeasure, exploredMeasures));
|
|
57433
|
+
}
|
|
57434
|
+
rangeDependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
|
|
57435
|
+
return rangeDependencies;
|
|
57436
|
+
}
|
|
57326
57437
|
insertPivot(position, formulaId, table) {
|
|
57327
57438
|
this.resizeSheet(position.sheetId, position, table);
|
|
57328
57439
|
const pivotCells = table.getPivotCells();
|
|
@@ -57379,28 +57490,17 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
57379
57490
|
dependencies: rangeDependencies,
|
|
57380
57491
|
};
|
|
57381
57492
|
}
|
|
57382
|
-
replaceMeasureFormula(
|
|
57383
|
-
|
|
57384
|
-
|
|
57385
|
-
|
|
57386
|
-
const pivot = this.pivots[pivotId];
|
|
57387
|
-
if (!pivot) {
|
|
57388
|
-
continue;
|
|
57389
|
-
}
|
|
57390
|
-
const def = deepCopy(pivot.definition);
|
|
57391
|
-
for (const measure of def.measures) {
|
|
57392
|
-
if (measure.computedBy?.formula === formulaString) {
|
|
57393
|
-
const measureIndex = def.measures.indexOf(measure);
|
|
57394
|
-
if (measureIndex !== -1) {
|
|
57395
|
-
def.measures[measureIndex].computedBy = {
|
|
57396
|
-
formula: newFormulaString,
|
|
57397
|
-
sheetId,
|
|
57398
|
-
};
|
|
57399
|
-
}
|
|
57400
|
-
this.dispatch("UPDATE_PIVOT", { pivotId, pivot: def });
|
|
57401
|
-
}
|
|
57402
|
-
}
|
|
57493
|
+
replaceMeasureFormula(pivotId, measure, newFormulaString) {
|
|
57494
|
+
const pivot = this.pivots[pivotId];
|
|
57495
|
+
if (!pivot) {
|
|
57496
|
+
return;
|
|
57403
57497
|
}
|
|
57498
|
+
const measureIndex = pivot.definition.measures.indexOf(measure);
|
|
57499
|
+
this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", {
|
|
57500
|
+
formula: newFormulaString,
|
|
57501
|
+
sheetId: measure.computedBy.sheetId,
|
|
57502
|
+
});
|
|
57503
|
+
this.compileCalculatedMeasures(pivotId, pivot.definition.measures);
|
|
57404
57504
|
}
|
|
57405
57505
|
checkDuplicatedMeasureIds(definition) {
|
|
57406
57506
|
const uniqueIds = new Set(definition.measures.map((m) => m.id));
|
|
@@ -57496,20 +57596,6 @@ class SettingsPlugin extends CorePlugin {
|
|
|
57496
57596
|
}
|
|
57497
57597
|
}
|
|
57498
57598
|
|
|
57499
|
-
function adaptPivotRange(range, applyChange) {
|
|
57500
|
-
if (!range) {
|
|
57501
|
-
return undefined;
|
|
57502
|
-
}
|
|
57503
|
-
const change = applyChange(range);
|
|
57504
|
-
switch (change.changeType) {
|
|
57505
|
-
case "NONE":
|
|
57506
|
-
return range;
|
|
57507
|
-
case "REMOVE":
|
|
57508
|
-
return undefined;
|
|
57509
|
-
default:
|
|
57510
|
-
return change.range;
|
|
57511
|
-
}
|
|
57512
|
-
}
|
|
57513
57599
|
class SpreadsheetPivotCorePlugin extends CorePlugin {
|
|
57514
57600
|
allowDispatch(cmd) {
|
|
57515
57601
|
switch (cmd.type) {
|
|
@@ -57520,27 +57606,6 @@ class SpreadsheetPivotCorePlugin extends CorePlugin {
|
|
|
57520
57606
|
}
|
|
57521
57607
|
return "Success" /* CommandResult.Success */;
|
|
57522
57608
|
}
|
|
57523
|
-
adaptRanges(applyChange) {
|
|
57524
|
-
for (const pivotId of this.getters.getPivotIds()) {
|
|
57525
|
-
const definition = this.getters.getPivotCoreDefinition(pivotId);
|
|
57526
|
-
if (definition.type !== "SPREADSHEET") {
|
|
57527
|
-
continue;
|
|
57528
|
-
}
|
|
57529
|
-
if (definition.dataSet) {
|
|
57530
|
-
const { sheetId, zone } = definition.dataSet;
|
|
57531
|
-
const range = this.getters.getRangeFromZone(sheetId, zone);
|
|
57532
|
-
const adaptedRange = adaptPivotRange(range, applyChange);
|
|
57533
|
-
if (adaptedRange === range) {
|
|
57534
|
-
return;
|
|
57535
|
-
}
|
|
57536
|
-
const dataSet = adaptedRange && {
|
|
57537
|
-
sheetId: adaptedRange.sheetId,
|
|
57538
|
-
zone: adaptedRange.zone,
|
|
57539
|
-
};
|
|
57540
|
-
this.dispatch("UPDATE_PIVOT", { pivotId, pivot: { ...definition, dataSet } });
|
|
57541
|
-
}
|
|
57542
|
-
}
|
|
57543
|
-
}
|
|
57544
57609
|
checkDataSetValidity(definition) {
|
|
57545
57610
|
if (definition.type === "SPREADSHEET" && definition.dataSet) {
|
|
57546
57611
|
const { zone, sheetId } = definition.dataSet;
|
|
@@ -58898,6 +58963,9 @@ class Evaluator {
|
|
|
58898
58963
|
const arrayFormulas = this.spreadingRelations.searchFormulaPositionsSpreadingOn(position.sheetId, positionToZone(position));
|
|
58899
58964
|
return Array.from(arrayFormulas).find((position) => !this.blockedArrayFormulas.has(position));
|
|
58900
58965
|
}
|
|
58966
|
+
isArrayFormulaSpillBlocked(position) {
|
|
58967
|
+
return this.blockedArrayFormulas.has(position);
|
|
58968
|
+
}
|
|
58901
58969
|
updateDependencies(position) {
|
|
58902
58970
|
// removing dependencies is slow because it requires
|
|
58903
58971
|
// to traverse the entire r-tree.
|
|
@@ -58909,13 +58977,8 @@ class Evaluator {
|
|
|
58909
58977
|
addDependencies(position, dependencies) {
|
|
58910
58978
|
this.formulaDependencies().addDependencies(position, dependencies);
|
|
58911
58979
|
for (const range of dependencies) {
|
|
58912
|
-
|
|
58913
|
-
|
|
58914
|
-
for (let col = left; col <= right; col++) {
|
|
58915
|
-
for (let row = top; row <= bottom; row++) {
|
|
58916
|
-
this.computeAndSave({ sheetId, col, row });
|
|
58917
|
-
}
|
|
58918
|
-
}
|
|
58980
|
+
// ensure that all ranges are computed
|
|
58981
|
+
this.compilationParams.ensureRange(range);
|
|
58919
58982
|
}
|
|
58920
58983
|
}
|
|
58921
58984
|
updateCompilationParameters() {
|
|
@@ -59114,6 +59177,10 @@ class Evaluator {
|
|
|
59114
59177
|
this.assertSheetHasEnoughSpaceToSpreadFormulaResult(formulaPosition, formulaReturn);
|
|
59115
59178
|
const nbColumns = formulaReturn.length;
|
|
59116
59179
|
const nbRows = formulaReturn[0].length;
|
|
59180
|
+
if (nbRows === 0) {
|
|
59181
|
+
// empty matrix
|
|
59182
|
+
return createEvaluatedCell({ value: 0 }, this.getters.getLocale(), cellData);
|
|
59183
|
+
}
|
|
59117
59184
|
const resultZone = {
|
|
59118
59185
|
top: formulaPosition.row,
|
|
59119
59186
|
bottom: formulaPosition.row + nbRows - 1,
|
|
@@ -59386,6 +59453,7 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
59386
59453
|
"getEvaluatedCellsPositions",
|
|
59387
59454
|
"getSpreadZone",
|
|
59388
59455
|
"getArrayFormulaSpreadingOn",
|
|
59456
|
+
"isArrayFormulaSpillBlocked",
|
|
59389
59457
|
"isEmpty",
|
|
59390
59458
|
];
|
|
59391
59459
|
shouldRebuildDependenciesGraph = true;
|
|
@@ -59498,6 +59566,9 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
59498
59566
|
getArrayFormulaSpreadingOn(position) {
|
|
59499
59567
|
return this.evaluator.getArrayFormulaSpreadingOn(position);
|
|
59500
59568
|
}
|
|
59569
|
+
isArrayFormulaSpillBlocked(position) {
|
|
59570
|
+
return this.evaluator.isArrayFormulaSpillBlocked(position);
|
|
59571
|
+
}
|
|
59501
59572
|
/**
|
|
59502
59573
|
* Check if a zone only contains empty cells
|
|
59503
59574
|
*/
|
|
@@ -60721,14 +60792,16 @@ const PERCENT_FORMAT = "0.00%";
|
|
|
60721
60792
|
function withPivotPresentationLayer (PivotClass) {
|
|
60722
60793
|
class PivotPresentationLayer extends PivotClass {
|
|
60723
60794
|
getters;
|
|
60795
|
+
pivotId;
|
|
60724
60796
|
cache = {};
|
|
60725
60797
|
rankAsc = {};
|
|
60726
60798
|
rankDesc = {};
|
|
60727
60799
|
runningTotal = {};
|
|
60728
60800
|
runningTotalInPercent = {};
|
|
60729
|
-
constructor(custom, params) {
|
|
60801
|
+
constructor(pivotId, custom, params) {
|
|
60730
60802
|
super(custom, params);
|
|
60731
60803
|
this.getters = params.getters;
|
|
60804
|
+
this.pivotId = pivotId;
|
|
60732
60805
|
}
|
|
60733
60806
|
markAsDirtyForEvaluation() {
|
|
60734
60807
|
this.cache = {};
|
|
@@ -60778,7 +60851,7 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
60778
60851
|
return handleError(error, measure.aggregator.toUpperCase());
|
|
60779
60852
|
}
|
|
60780
60853
|
}
|
|
60781
|
-
const formula = this.getters.getMeasureCompiledFormula(measure);
|
|
60854
|
+
const formula = this.getters.getMeasureCompiledFormula(this.pivotId, measure);
|
|
60782
60855
|
const getSymbolValue = (symbolName) => {
|
|
60783
60856
|
const { columns, rows } = this.definition;
|
|
60784
60857
|
if (columns.find((col) => col.nameWithGranularity === symbolName)) {
|
|
@@ -61496,7 +61569,7 @@ class PivotUIPlugin extends UIPlugin {
|
|
|
61496
61569
|
const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
|
|
61497
61570
|
if (!(pivotId in this.pivots)) {
|
|
61498
61571
|
const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
|
|
61499
|
-
this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
|
|
61572
|
+
this.pivots[pivotId] = new Pivot(pivotId, this.custom, { definition, getters: this.getters });
|
|
61500
61573
|
}
|
|
61501
61574
|
else if (recreate) {
|
|
61502
61575
|
this.pivots[pivotId].onDefinitionChange(definition);
|
|
@@ -74770,6 +74843,6 @@ exports.tokenColors = tokenColors;
|
|
|
74770
74843
|
exports.tokenize = tokenize;
|
|
74771
74844
|
|
|
74772
74845
|
|
|
74773
|
-
__info__.version = "18.0.
|
|
74774
|
-
__info__.date = "
|
|
74775
|
-
__info__.hash = "
|
|
74846
|
+
__info__.version = "18.0.54";
|
|
74847
|
+
__info__.date = "2026-01-14T10:00:02.287Z";
|
|
74848
|
+
__info__.hash = "c0048a0";
|