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