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