@odoo/o-spreadsheet 18.4.23 → 18.4.24
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 +94 -44
- package/dist/o-spreadsheet.d.ts +10 -4
- package/dist/o-spreadsheet.esm.js +94 -44
- package/dist/o-spreadsheet.iife.js +94 -44
- package/dist/o-spreadsheet.iife.min.js +6 -6
- package/dist/o_spreadsheet.css +3 -3
- package/dist/o_spreadsheet.xml +5 -4
- 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.4.
|
|
6
|
-
* @date 2026-01-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.4.24
|
|
6
|
+
* @date 2026-01-14T10:00:55.867Z
|
|
7
|
+
* @hash 0364f56
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -19070,9 +19070,10 @@ function assertDomainLength(domain) {
|
|
|
19070
19070
|
throw new EvaluationError(_t("Function PIVOT takes an even number of arguments."));
|
|
19071
19071
|
}
|
|
19072
19072
|
}
|
|
19073
|
-
function addPivotDependencies(evalContext,
|
|
19073
|
+
function addPivotDependencies(evalContext, pivotId, forMeasures) {
|
|
19074
19074
|
//TODO This function can be very costly when used with PIVOT.VALUE and PIVOT.HEADER
|
|
19075
19075
|
const dependencies = [];
|
|
19076
|
+
const coreDefinition = evalContext.getters.getPivotCoreDefinition(pivotId);
|
|
19076
19077
|
if (coreDefinition.type === "SPREADSHEET" && coreDefinition.dataSet) {
|
|
19077
19078
|
const { sheetId, zone } = coreDefinition.dataSet;
|
|
19078
19079
|
const xc = zoneToXc(zone);
|
|
@@ -19089,8 +19090,7 @@ function addPivotDependencies(evalContext, coreDefinition, forMeasures) {
|
|
|
19089
19090
|
}
|
|
19090
19091
|
for (const measure of forMeasures) {
|
|
19091
19092
|
if (measure.computedBy) {
|
|
19092
|
-
|
|
19093
|
-
dependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
|
|
19093
|
+
dependencies.push(...evalContext.getters.getMeasureFullDependencies(pivotId, measure));
|
|
19094
19094
|
}
|
|
19095
19095
|
}
|
|
19096
19096
|
const originPosition = evalContext.__originCellPosition;
|
|
@@ -19559,7 +19559,7 @@ const PIVOT_VALUE = {
|
|
|
19559
19559
|
assertDomainLength(domainArgs);
|
|
19560
19560
|
const pivot = this.getters.getPivot(pivotId);
|
|
19561
19561
|
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
19562
|
-
addPivotDependencies(this,
|
|
19562
|
+
addPivotDependencies(this, pivotId, coreDefinition.measures.filter((m) => m.id === _measure));
|
|
19563
19563
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
19564
19564
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
19565
19565
|
if (error) {
|
|
@@ -19592,8 +19592,7 @@ const PIVOT_HEADER = {
|
|
|
19592
19592
|
const _pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
19593
19593
|
assertDomainLength(domainArgs);
|
|
19594
19594
|
const pivot = this.getters.getPivot(_pivotId);
|
|
19595
|
-
|
|
19596
|
-
addPivotDependencies(this, coreDefinition, []);
|
|
19595
|
+
addPivotDependencies(this, _pivotId, []);
|
|
19597
19596
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
19598
19597
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
19599
19598
|
if (error) {
|
|
@@ -19651,7 +19650,7 @@ const PIVOT = {
|
|
|
19651
19650
|
const pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
19652
19651
|
const pivot = this.getters.getPivot(pivotId);
|
|
19653
19652
|
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
19654
|
-
addPivotDependencies(this,
|
|
19653
|
+
addPivotDependencies(this, pivotId, coreDefinition.measures);
|
|
19655
19654
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
19656
19655
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
19657
19656
|
if (error) {
|
|
@@ -32905,7 +32904,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
32905
32904
|
}
|
|
32906
32905
|
captureSelection(zone, col, row) {
|
|
32907
32906
|
this.model.selection.capture(this, {
|
|
32908
|
-
cell: { col: col ?? zone.left, row: row ?? zone.
|
|
32907
|
+
cell: { col: col ?? zone.left, row: row ?? zone.top },
|
|
32909
32908
|
zone,
|
|
32910
32909
|
}, {
|
|
32911
32910
|
handleEvent: this.handleEvent.bind(this),
|
|
@@ -53205,6 +53204,12 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
53205
53204
|
case "ACTIVATE_SHEET":
|
|
53206
53205
|
this.isSearchDirty = true;
|
|
53207
53206
|
this.shouldFinalizeUpdateSelection = true;
|
|
53207
|
+
if (this.searchOptions.specificRange) {
|
|
53208
|
+
this.searchOptions.specificRange = {
|
|
53209
|
+
...this.searchOptions.specificRange,
|
|
53210
|
+
sheetId: this.getters.getActiveSheetId(),
|
|
53211
|
+
};
|
|
53212
|
+
}
|
|
53208
53213
|
break;
|
|
53209
53214
|
case "REPLACE_SEARCH":
|
|
53210
53215
|
for (const match of cmd.matches) {
|
|
@@ -53624,9 +53629,20 @@ class FindAndReplacePanel extends owl.Component {
|
|
|
53624
53629
|
const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.dataRange);
|
|
53625
53630
|
this.store.updateSearchOptions({ specificRange });
|
|
53626
53631
|
}
|
|
53632
|
+
get specificRange() {
|
|
53633
|
+
const range = this.store.searchOptions.specificRange;
|
|
53634
|
+
return range ? this.env.model.getters.getRangeString(range, "forceSheetReference") : "";
|
|
53635
|
+
}
|
|
53627
53636
|
get pendingSearch() {
|
|
53628
53637
|
return this.updateSearchContent.isDebouncePending();
|
|
53629
53638
|
}
|
|
53639
|
+
get selectionInputKey() {
|
|
53640
|
+
// Selections input are made to work with objects linked to a sheet id. They store the active sheet id at their creation,
|
|
53641
|
+
// and have specific behaviour linked to it (eg. go back to the initial sheet after confirmation).
|
|
53642
|
+
// We don't want all those behaviors here, so we force the recreation of the component when the active sheet changes.
|
|
53643
|
+
// The only drawback is that the input loses focus when changing sheet.
|
|
53644
|
+
return this.env.model.getters.getActiveSheetId();
|
|
53645
|
+
}
|
|
53630
53646
|
}
|
|
53631
53647
|
|
|
53632
53648
|
css /* scss */ `
|
|
@@ -64253,6 +64269,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
64253
64269
|
"getMeasureCompiledFormula",
|
|
64254
64270
|
"getPivotName",
|
|
64255
64271
|
"isExistingPivot",
|
|
64272
|
+
"getMeasureFullDependencies",
|
|
64256
64273
|
];
|
|
64257
64274
|
nextFormulaId = 1;
|
|
64258
64275
|
pivots = {};
|
|
@@ -64335,7 +64352,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
64335
64352
|
}
|
|
64336
64353
|
case "UPDATE_PIVOT": {
|
|
64337
64354
|
this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
|
|
64338
|
-
this.compileCalculatedMeasures(cmd.pivot.measures);
|
|
64355
|
+
this.compileCalculatedMeasures(cmd.pivotId, cmd.pivot.measures);
|
|
64339
64356
|
break;
|
|
64340
64357
|
}
|
|
64341
64358
|
}
|
|
@@ -64353,9 +64370,14 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
64353
64370
|
this.history.update("pivots", pivotId, "definition", newDefinition);
|
|
64354
64371
|
}
|
|
64355
64372
|
}
|
|
64356
|
-
for (const
|
|
64357
|
-
for (const
|
|
64358
|
-
const
|
|
64373
|
+
for (const pivotId in this.compiledMeasureFormulas) {
|
|
64374
|
+
for (const measureId in this.compiledMeasureFormulas[pivotId]) {
|
|
64375
|
+
const measure = this.pivots[pivotId]?.definition.measures.find((m) => m.id === measureId);
|
|
64376
|
+
if (!measure || !measure.computedBy) {
|
|
64377
|
+
continue;
|
|
64378
|
+
}
|
|
64379
|
+
const sheetId = measure.computedBy.sheetId;
|
|
64380
|
+
const compiledFormula = this.compiledMeasureFormulas[pivotId][measureId].formula;
|
|
64359
64381
|
const newDependencies = [];
|
|
64360
64382
|
for (const range of compiledFormula.dependencies) {
|
|
64361
64383
|
const change = applyChange(range);
|
|
@@ -64367,8 +64389,9 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
64367
64389
|
}
|
|
64368
64390
|
}
|
|
64369
64391
|
const newFormulaString = this.getters.getFormulaString(sheetId, compiledFormula.tokens, newDependencies);
|
|
64370
|
-
|
|
64371
|
-
|
|
64392
|
+
const oldFormulaString = measure.computedBy.formula;
|
|
64393
|
+
if (newFormulaString !== oldFormulaString) {
|
|
64394
|
+
this.replaceMeasureFormula(pivotId, measure, newFormulaString);
|
|
64372
64395
|
}
|
|
64373
64396
|
}
|
|
64374
64397
|
}
|
|
@@ -64406,30 +64429,59 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
64406
64429
|
isExistingPivot(pivotId) {
|
|
64407
64430
|
return pivotId in this.pivots;
|
|
64408
64431
|
}
|
|
64409
|
-
getMeasureCompiledFormula(measure) {
|
|
64432
|
+
getMeasureCompiledFormula(pivotId, measure) {
|
|
64410
64433
|
if (!measure.computedBy) {
|
|
64411
64434
|
throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
|
|
64412
64435
|
}
|
|
64413
|
-
|
|
64414
|
-
|
|
64436
|
+
return this.compiledMeasureFormulas[pivotId][measure.id].formula;
|
|
64437
|
+
}
|
|
64438
|
+
getMeasureFullDependencies(pivotId, measure) {
|
|
64439
|
+
if (!measure.computedBy) {
|
|
64440
|
+
throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
|
|
64441
|
+
}
|
|
64442
|
+
return this.compiledMeasureFormulas[pivotId][measure.id].dependencies;
|
|
64415
64443
|
}
|
|
64416
64444
|
// -------------------------------------------------------------------------
|
|
64417
64445
|
// Private
|
|
64418
64446
|
// -------------------------------------------------------------------------
|
|
64419
64447
|
addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
|
|
64420
64448
|
this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
|
|
64421
|
-
this.compileCalculatedMeasures(pivot.measures);
|
|
64449
|
+
this.compileCalculatedMeasures(pivotId, pivot.measures);
|
|
64422
64450
|
this.history.update("formulaIds", formulaId, pivotId);
|
|
64423
64451
|
this.history.update("nextFormulaId", this.nextFormulaId + 1);
|
|
64424
64452
|
}
|
|
64425
|
-
compileCalculatedMeasures(measures) {
|
|
64453
|
+
compileCalculatedMeasures(pivotId, measures) {
|
|
64426
64454
|
for (const measure of measures) {
|
|
64427
64455
|
if (measure.computedBy) {
|
|
64428
|
-
const sheetId = measure.computedBy.sheetId;
|
|
64429
64456
|
const compiledFormula = this.compileMeasureFormula(measure.computedBy.sheetId, measure.computedBy.formula);
|
|
64430
|
-
this.history.update("compiledMeasureFormulas",
|
|
64457
|
+
this.history.update("compiledMeasureFormulas", pivotId, measure.id, "formula", compiledFormula);
|
|
64431
64458
|
}
|
|
64432
64459
|
}
|
|
64460
|
+
for (const measure of measures) {
|
|
64461
|
+
if (measure.computedBy) {
|
|
64462
|
+
const dependencies = this.computeMeasureFullDependencies(pivotId, measure);
|
|
64463
|
+
this.history.update("compiledMeasureFormulas", pivotId, measure.id, "dependencies", dependencies);
|
|
64464
|
+
}
|
|
64465
|
+
}
|
|
64466
|
+
}
|
|
64467
|
+
computeMeasureFullDependencies(pivotId, measure, exploredMeasures = new Set()) {
|
|
64468
|
+
const rangeDependencies = [];
|
|
64469
|
+
const definition = this.getPivotCoreDefinition(pivotId);
|
|
64470
|
+
const formula = this.getMeasureCompiledFormula(pivotId, measure);
|
|
64471
|
+
exploredMeasures.add(measure.id);
|
|
64472
|
+
for (const token of formula.tokens) {
|
|
64473
|
+
if (token.type !== "SYMBOL") {
|
|
64474
|
+
continue;
|
|
64475
|
+
}
|
|
64476
|
+
const otherMeasure = definition.measures.find((measureCandidate) => getCanonicalSymbolName(measureCandidate.id) === token.value &&
|
|
64477
|
+
measure.id !== measureCandidate.id);
|
|
64478
|
+
if (!otherMeasure || exploredMeasures.has(otherMeasure.id) || !otherMeasure.computedBy) {
|
|
64479
|
+
continue;
|
|
64480
|
+
}
|
|
64481
|
+
rangeDependencies.push(...this.computeMeasureFullDependencies(pivotId, otherMeasure, exploredMeasures));
|
|
64482
|
+
}
|
|
64483
|
+
rangeDependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
|
|
64484
|
+
return rangeDependencies;
|
|
64433
64485
|
}
|
|
64434
64486
|
insertPivot(position, formulaId, table) {
|
|
64435
64487
|
this.resizeSheet(position.sheetId, position, table);
|
|
@@ -64489,21 +64541,17 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
64489
64541
|
dependencies: rangeDependencies,
|
|
64490
64542
|
};
|
|
64491
64543
|
}
|
|
64492
|
-
replaceMeasureFormula(
|
|
64493
|
-
|
|
64494
|
-
|
|
64495
|
-
|
|
64496
|
-
const pivot = this.pivots[pivotId];
|
|
64497
|
-
if (!pivot) {
|
|
64498
|
-
continue;
|
|
64499
|
-
}
|
|
64500
|
-
for (const measure of pivot.definition.measures) {
|
|
64501
|
-
if (measure.computedBy?.formula === formulaString) {
|
|
64502
|
-
const measureIndex = pivot.definition.measures.indexOf(measure);
|
|
64503
|
-
this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", { formula: newFormulaString, sheetId });
|
|
64504
|
-
}
|
|
64505
|
-
}
|
|
64544
|
+
replaceMeasureFormula(pivotId, measure, newFormulaString) {
|
|
64545
|
+
const pivot = this.pivots[pivotId];
|
|
64546
|
+
if (!pivot) {
|
|
64547
|
+
return;
|
|
64506
64548
|
}
|
|
64549
|
+
const measureIndex = pivot.definition.measures.indexOf(measure);
|
|
64550
|
+
this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", {
|
|
64551
|
+
formula: newFormulaString,
|
|
64552
|
+
sheetId: measure.computedBy.sheetId,
|
|
64553
|
+
});
|
|
64554
|
+
this.compileCalculatedMeasures(pivotId, pivot.definition.measures);
|
|
64507
64555
|
}
|
|
64508
64556
|
checkSortedColumnInMeasures(definition) {
|
|
64509
64557
|
const measures = definition.measures.map((measure) => measure.id);
|
|
@@ -68031,14 +68079,16 @@ const PERCENT_FORMAT = "0.00%";
|
|
|
68031
68079
|
function withPivotPresentationLayer (PivotClass) {
|
|
68032
68080
|
class PivotPresentationLayer extends PivotClass {
|
|
68033
68081
|
getters;
|
|
68082
|
+
pivotId;
|
|
68034
68083
|
cache = {};
|
|
68035
68084
|
rankAsc = {};
|
|
68036
68085
|
rankDesc = {};
|
|
68037
68086
|
runningTotal = {};
|
|
68038
68087
|
runningTotalInPercent = {};
|
|
68039
|
-
constructor(custom, params) {
|
|
68088
|
+
constructor(pivotId, custom, params) {
|
|
68040
68089
|
super(custom, params);
|
|
68041
68090
|
this.getters = params.getters;
|
|
68091
|
+
this.pivotId = pivotId;
|
|
68042
68092
|
}
|
|
68043
68093
|
markAsDirtyForEvaluation() {
|
|
68044
68094
|
this.cache = {};
|
|
@@ -68088,7 +68138,7 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
68088
68138
|
return handleError(error, measure.aggregator.toUpperCase());
|
|
68089
68139
|
}
|
|
68090
68140
|
}
|
|
68091
|
-
const formula = this.getters.getMeasureCompiledFormula(measure);
|
|
68141
|
+
const formula = this.getters.getMeasureCompiledFormula(this.pivotId, measure);
|
|
68092
68142
|
const getSymbolValue = (symbolName) => {
|
|
68093
68143
|
const { columns, rows } = this.definition;
|
|
68094
68144
|
if (columns.find((col) => col.nameWithGranularity === symbolName)) {
|
|
@@ -68828,7 +68878,7 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
68828
68878
|
const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
|
|
68829
68879
|
if (!(pivotId in this.pivots)) {
|
|
68830
68880
|
const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
|
|
68831
|
-
this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
|
|
68881
|
+
this.pivots[pivotId] = new Pivot(pivotId, this.custom, { definition, getters: this.getters });
|
|
68832
68882
|
}
|
|
68833
68883
|
else if (recreate) {
|
|
68834
68884
|
this.pivots[pivotId].onDefinitionChange(definition);
|
|
@@ -85014,6 +85064,6 @@ exports.tokenColors = tokenColors;
|
|
|
85014
85064
|
exports.tokenize = tokenize;
|
|
85015
85065
|
|
|
85016
85066
|
|
|
85017
|
-
__info__.version = "18.4.
|
|
85018
|
-
__info__.date = "2026-01-
|
|
85019
|
-
__info__.hash = "
|
|
85067
|
+
__info__.version = "18.4.24";
|
|
85068
|
+
__info__.date = "2026-01-14T10:00:55.867Z";
|
|
85069
|
+
__info__.hash = "0364f56";
|
package/dist/o-spreadsheet.d.ts
CHANGED
|
@@ -5151,14 +5151,18 @@ interface Pivot$1 {
|
|
|
5151
5151
|
definition: PivotCoreDefinition;
|
|
5152
5152
|
formulaId: string;
|
|
5153
5153
|
}
|
|
5154
|
+
interface MeasureState {
|
|
5155
|
+
formula: RangeCompiledFormula;
|
|
5156
|
+
dependencies: Range[];
|
|
5157
|
+
}
|
|
5154
5158
|
interface CoreState {
|
|
5155
5159
|
nextFormulaId: number;
|
|
5156
5160
|
pivots: Record<UID, Pivot$1 | undefined>;
|
|
5157
5161
|
formulaIds: Record<UID, string | undefined>;
|
|
5158
|
-
compiledMeasureFormulas: Record<UID, Record<string,
|
|
5162
|
+
compiledMeasureFormulas: Record<UID, Record<string, MeasureState | undefined>>;
|
|
5159
5163
|
}
|
|
5160
5164
|
declare class PivotCorePlugin extends CorePlugin<CoreState> implements CoreState {
|
|
5161
|
-
static getters: readonly ["getPivotCoreDefinition", "getPivotDisplayName", "getPivotId", "getPivotFormulaId", "getPivotIds", "getMeasureCompiledFormula", "getPivotName", "isExistingPivot"];
|
|
5165
|
+
static getters: readonly ["getPivotCoreDefinition", "getPivotDisplayName", "getPivotId", "getPivotFormulaId", "getPivotIds", "getMeasureCompiledFormula", "getPivotName", "isExistingPivot", "getMeasureFullDependencies"];
|
|
5162
5166
|
readonly nextFormulaId: number;
|
|
5163
5167
|
readonly pivots: {
|
|
5164
5168
|
[pivotId: UID]: Pivot$1 | undefined;
|
|
@@ -5166,7 +5170,7 @@ declare class PivotCorePlugin extends CorePlugin<CoreState> implements CoreState
|
|
|
5166
5170
|
readonly formulaIds: {
|
|
5167
5171
|
[formulaId: UID]: UID | undefined;
|
|
5168
5172
|
};
|
|
5169
|
-
readonly compiledMeasureFormulas: Record<UID, Record<string,
|
|
5173
|
+
readonly compiledMeasureFormulas: Record<UID, Record<string, MeasureState>>;
|
|
5170
5174
|
allowDispatch(cmd: CoreCommand): CommandResult | CommandResult[];
|
|
5171
5175
|
handle(cmd: CoreCommand): void;
|
|
5172
5176
|
adaptRanges(applyChange: ApplyRangeChange): void;
|
|
@@ -5185,9 +5189,11 @@ declare class PivotCorePlugin extends CorePlugin<CoreState> implements CoreState
|
|
|
5185
5189
|
getPivotFormulaId(pivotId: UID): string;
|
|
5186
5190
|
getPivotIds(): UID[];
|
|
5187
5191
|
isExistingPivot(pivotId: UID): boolean;
|
|
5188
|
-
getMeasureCompiledFormula(measure: PivotCoreMeasure): RangeCompiledFormula;
|
|
5192
|
+
getMeasureCompiledFormula(pivotId: UID, measure: PivotCoreMeasure): RangeCompiledFormula;
|
|
5193
|
+
getMeasureFullDependencies(pivotId: UID, measure: PivotCoreMeasure): Range[];
|
|
5189
5194
|
private addPivot;
|
|
5190
5195
|
private compileCalculatedMeasures;
|
|
5196
|
+
private computeMeasureFullDependencies;
|
|
5191
5197
|
private insertPivot;
|
|
5192
5198
|
private resizeSheet;
|
|
5193
5199
|
private getPivotCore;
|
|
@@ -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.4.
|
|
6
|
-
* @date 2026-01-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.4.24
|
|
6
|
+
* @date 2026-01-14T10:00:55.867Z
|
|
7
|
+
* @hash 0364f56
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, useExternalListener, onWillUpdateProps, onWillStart, onWillPatch, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -19068,9 +19068,10 @@ function assertDomainLength(domain) {
|
|
|
19068
19068
|
throw new EvaluationError(_t("Function PIVOT takes an even number of arguments."));
|
|
19069
19069
|
}
|
|
19070
19070
|
}
|
|
19071
|
-
function addPivotDependencies(evalContext,
|
|
19071
|
+
function addPivotDependencies(evalContext, pivotId, forMeasures) {
|
|
19072
19072
|
//TODO This function can be very costly when used with PIVOT.VALUE and PIVOT.HEADER
|
|
19073
19073
|
const dependencies = [];
|
|
19074
|
+
const coreDefinition = evalContext.getters.getPivotCoreDefinition(pivotId);
|
|
19074
19075
|
if (coreDefinition.type === "SPREADSHEET" && coreDefinition.dataSet) {
|
|
19075
19076
|
const { sheetId, zone } = coreDefinition.dataSet;
|
|
19076
19077
|
const xc = zoneToXc(zone);
|
|
@@ -19087,8 +19088,7 @@ function addPivotDependencies(evalContext, coreDefinition, forMeasures) {
|
|
|
19087
19088
|
}
|
|
19088
19089
|
for (const measure of forMeasures) {
|
|
19089
19090
|
if (measure.computedBy) {
|
|
19090
|
-
|
|
19091
|
-
dependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
|
|
19091
|
+
dependencies.push(...evalContext.getters.getMeasureFullDependencies(pivotId, measure));
|
|
19092
19092
|
}
|
|
19093
19093
|
}
|
|
19094
19094
|
const originPosition = evalContext.__originCellPosition;
|
|
@@ -19557,7 +19557,7 @@ const PIVOT_VALUE = {
|
|
|
19557
19557
|
assertDomainLength(domainArgs);
|
|
19558
19558
|
const pivot = this.getters.getPivot(pivotId);
|
|
19559
19559
|
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
19560
|
-
addPivotDependencies(this,
|
|
19560
|
+
addPivotDependencies(this, pivotId, coreDefinition.measures.filter((m) => m.id === _measure));
|
|
19561
19561
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
19562
19562
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
19563
19563
|
if (error) {
|
|
@@ -19590,8 +19590,7 @@ const PIVOT_HEADER = {
|
|
|
19590
19590
|
const _pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
19591
19591
|
assertDomainLength(domainArgs);
|
|
19592
19592
|
const pivot = this.getters.getPivot(_pivotId);
|
|
19593
|
-
|
|
19594
|
-
addPivotDependencies(this, coreDefinition, []);
|
|
19593
|
+
addPivotDependencies(this, _pivotId, []);
|
|
19595
19594
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
19596
19595
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
19597
19596
|
if (error) {
|
|
@@ -19649,7 +19648,7 @@ const PIVOT = {
|
|
|
19649
19648
|
const pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
19650
19649
|
const pivot = this.getters.getPivot(pivotId);
|
|
19651
19650
|
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
19652
|
-
addPivotDependencies(this,
|
|
19651
|
+
addPivotDependencies(this, pivotId, coreDefinition.measures);
|
|
19653
19652
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
19654
19653
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
19655
19654
|
if (error) {
|
|
@@ -32903,7 +32902,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
32903
32902
|
}
|
|
32904
32903
|
captureSelection(zone, col, row) {
|
|
32905
32904
|
this.model.selection.capture(this, {
|
|
32906
|
-
cell: { col: col ?? zone.left, row: row ?? zone.
|
|
32905
|
+
cell: { col: col ?? zone.left, row: row ?? zone.top },
|
|
32907
32906
|
zone,
|
|
32908
32907
|
}, {
|
|
32909
32908
|
handleEvent: this.handleEvent.bind(this),
|
|
@@ -53203,6 +53202,12 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
53203
53202
|
case "ACTIVATE_SHEET":
|
|
53204
53203
|
this.isSearchDirty = true;
|
|
53205
53204
|
this.shouldFinalizeUpdateSelection = true;
|
|
53205
|
+
if (this.searchOptions.specificRange) {
|
|
53206
|
+
this.searchOptions.specificRange = {
|
|
53207
|
+
...this.searchOptions.specificRange,
|
|
53208
|
+
sheetId: this.getters.getActiveSheetId(),
|
|
53209
|
+
};
|
|
53210
|
+
}
|
|
53206
53211
|
break;
|
|
53207
53212
|
case "REPLACE_SEARCH":
|
|
53208
53213
|
for (const match of cmd.matches) {
|
|
@@ -53622,9 +53627,20 @@ class FindAndReplacePanel extends Component {
|
|
|
53622
53627
|
const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.dataRange);
|
|
53623
53628
|
this.store.updateSearchOptions({ specificRange });
|
|
53624
53629
|
}
|
|
53630
|
+
get specificRange() {
|
|
53631
|
+
const range = this.store.searchOptions.specificRange;
|
|
53632
|
+
return range ? this.env.model.getters.getRangeString(range, "forceSheetReference") : "";
|
|
53633
|
+
}
|
|
53625
53634
|
get pendingSearch() {
|
|
53626
53635
|
return this.updateSearchContent.isDebouncePending();
|
|
53627
53636
|
}
|
|
53637
|
+
get selectionInputKey() {
|
|
53638
|
+
// Selections input are made to work with objects linked to a sheet id. They store the active sheet id at their creation,
|
|
53639
|
+
// and have specific behaviour linked to it (eg. go back to the initial sheet after confirmation).
|
|
53640
|
+
// We don't want all those behaviors here, so we force the recreation of the component when the active sheet changes.
|
|
53641
|
+
// The only drawback is that the input loses focus when changing sheet.
|
|
53642
|
+
return this.env.model.getters.getActiveSheetId();
|
|
53643
|
+
}
|
|
53628
53644
|
}
|
|
53629
53645
|
|
|
53630
53646
|
css /* scss */ `
|
|
@@ -64251,6 +64267,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
64251
64267
|
"getMeasureCompiledFormula",
|
|
64252
64268
|
"getPivotName",
|
|
64253
64269
|
"isExistingPivot",
|
|
64270
|
+
"getMeasureFullDependencies",
|
|
64254
64271
|
];
|
|
64255
64272
|
nextFormulaId = 1;
|
|
64256
64273
|
pivots = {};
|
|
@@ -64333,7 +64350,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
64333
64350
|
}
|
|
64334
64351
|
case "UPDATE_PIVOT": {
|
|
64335
64352
|
this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
|
|
64336
|
-
this.compileCalculatedMeasures(cmd.pivot.measures);
|
|
64353
|
+
this.compileCalculatedMeasures(cmd.pivotId, cmd.pivot.measures);
|
|
64337
64354
|
break;
|
|
64338
64355
|
}
|
|
64339
64356
|
}
|
|
@@ -64351,9 +64368,14 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
64351
64368
|
this.history.update("pivots", pivotId, "definition", newDefinition);
|
|
64352
64369
|
}
|
|
64353
64370
|
}
|
|
64354
|
-
for (const
|
|
64355
|
-
for (const
|
|
64356
|
-
const
|
|
64371
|
+
for (const pivotId in this.compiledMeasureFormulas) {
|
|
64372
|
+
for (const measureId in this.compiledMeasureFormulas[pivotId]) {
|
|
64373
|
+
const measure = this.pivots[pivotId]?.definition.measures.find((m) => m.id === measureId);
|
|
64374
|
+
if (!measure || !measure.computedBy) {
|
|
64375
|
+
continue;
|
|
64376
|
+
}
|
|
64377
|
+
const sheetId = measure.computedBy.sheetId;
|
|
64378
|
+
const compiledFormula = this.compiledMeasureFormulas[pivotId][measureId].formula;
|
|
64357
64379
|
const newDependencies = [];
|
|
64358
64380
|
for (const range of compiledFormula.dependencies) {
|
|
64359
64381
|
const change = applyChange(range);
|
|
@@ -64365,8 +64387,9 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
64365
64387
|
}
|
|
64366
64388
|
}
|
|
64367
64389
|
const newFormulaString = this.getters.getFormulaString(sheetId, compiledFormula.tokens, newDependencies);
|
|
64368
|
-
|
|
64369
|
-
|
|
64390
|
+
const oldFormulaString = measure.computedBy.formula;
|
|
64391
|
+
if (newFormulaString !== oldFormulaString) {
|
|
64392
|
+
this.replaceMeasureFormula(pivotId, measure, newFormulaString);
|
|
64370
64393
|
}
|
|
64371
64394
|
}
|
|
64372
64395
|
}
|
|
@@ -64404,30 +64427,59 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
64404
64427
|
isExistingPivot(pivotId) {
|
|
64405
64428
|
return pivotId in this.pivots;
|
|
64406
64429
|
}
|
|
64407
|
-
getMeasureCompiledFormula(measure) {
|
|
64430
|
+
getMeasureCompiledFormula(pivotId, measure) {
|
|
64408
64431
|
if (!measure.computedBy) {
|
|
64409
64432
|
throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
|
|
64410
64433
|
}
|
|
64411
|
-
|
|
64412
|
-
|
|
64434
|
+
return this.compiledMeasureFormulas[pivotId][measure.id].formula;
|
|
64435
|
+
}
|
|
64436
|
+
getMeasureFullDependencies(pivotId, measure) {
|
|
64437
|
+
if (!measure.computedBy) {
|
|
64438
|
+
throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
|
|
64439
|
+
}
|
|
64440
|
+
return this.compiledMeasureFormulas[pivotId][measure.id].dependencies;
|
|
64413
64441
|
}
|
|
64414
64442
|
// -------------------------------------------------------------------------
|
|
64415
64443
|
// Private
|
|
64416
64444
|
// -------------------------------------------------------------------------
|
|
64417
64445
|
addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
|
|
64418
64446
|
this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
|
|
64419
|
-
this.compileCalculatedMeasures(pivot.measures);
|
|
64447
|
+
this.compileCalculatedMeasures(pivotId, pivot.measures);
|
|
64420
64448
|
this.history.update("formulaIds", formulaId, pivotId);
|
|
64421
64449
|
this.history.update("nextFormulaId", this.nextFormulaId + 1);
|
|
64422
64450
|
}
|
|
64423
|
-
compileCalculatedMeasures(measures) {
|
|
64451
|
+
compileCalculatedMeasures(pivotId, measures) {
|
|
64424
64452
|
for (const measure of measures) {
|
|
64425
64453
|
if (measure.computedBy) {
|
|
64426
|
-
const sheetId = measure.computedBy.sheetId;
|
|
64427
64454
|
const compiledFormula = this.compileMeasureFormula(measure.computedBy.sheetId, measure.computedBy.formula);
|
|
64428
|
-
this.history.update("compiledMeasureFormulas",
|
|
64455
|
+
this.history.update("compiledMeasureFormulas", pivotId, measure.id, "formula", compiledFormula);
|
|
64429
64456
|
}
|
|
64430
64457
|
}
|
|
64458
|
+
for (const measure of measures) {
|
|
64459
|
+
if (measure.computedBy) {
|
|
64460
|
+
const dependencies = this.computeMeasureFullDependencies(pivotId, measure);
|
|
64461
|
+
this.history.update("compiledMeasureFormulas", pivotId, measure.id, "dependencies", dependencies);
|
|
64462
|
+
}
|
|
64463
|
+
}
|
|
64464
|
+
}
|
|
64465
|
+
computeMeasureFullDependencies(pivotId, measure, exploredMeasures = new Set()) {
|
|
64466
|
+
const rangeDependencies = [];
|
|
64467
|
+
const definition = this.getPivotCoreDefinition(pivotId);
|
|
64468
|
+
const formula = this.getMeasureCompiledFormula(pivotId, measure);
|
|
64469
|
+
exploredMeasures.add(measure.id);
|
|
64470
|
+
for (const token of formula.tokens) {
|
|
64471
|
+
if (token.type !== "SYMBOL") {
|
|
64472
|
+
continue;
|
|
64473
|
+
}
|
|
64474
|
+
const otherMeasure = definition.measures.find((measureCandidate) => getCanonicalSymbolName(measureCandidate.id) === token.value &&
|
|
64475
|
+
measure.id !== measureCandidate.id);
|
|
64476
|
+
if (!otherMeasure || exploredMeasures.has(otherMeasure.id) || !otherMeasure.computedBy) {
|
|
64477
|
+
continue;
|
|
64478
|
+
}
|
|
64479
|
+
rangeDependencies.push(...this.computeMeasureFullDependencies(pivotId, otherMeasure, exploredMeasures));
|
|
64480
|
+
}
|
|
64481
|
+
rangeDependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
|
|
64482
|
+
return rangeDependencies;
|
|
64431
64483
|
}
|
|
64432
64484
|
insertPivot(position, formulaId, table) {
|
|
64433
64485
|
this.resizeSheet(position.sheetId, position, table);
|
|
@@ -64487,21 +64539,17 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
64487
64539
|
dependencies: rangeDependencies,
|
|
64488
64540
|
};
|
|
64489
64541
|
}
|
|
64490
|
-
replaceMeasureFormula(
|
|
64491
|
-
|
|
64492
|
-
|
|
64493
|
-
|
|
64494
|
-
const pivot = this.pivots[pivotId];
|
|
64495
|
-
if (!pivot) {
|
|
64496
|
-
continue;
|
|
64497
|
-
}
|
|
64498
|
-
for (const measure of pivot.definition.measures) {
|
|
64499
|
-
if (measure.computedBy?.formula === formulaString) {
|
|
64500
|
-
const measureIndex = pivot.definition.measures.indexOf(measure);
|
|
64501
|
-
this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", { formula: newFormulaString, sheetId });
|
|
64502
|
-
}
|
|
64503
|
-
}
|
|
64542
|
+
replaceMeasureFormula(pivotId, measure, newFormulaString) {
|
|
64543
|
+
const pivot = this.pivots[pivotId];
|
|
64544
|
+
if (!pivot) {
|
|
64545
|
+
return;
|
|
64504
64546
|
}
|
|
64547
|
+
const measureIndex = pivot.definition.measures.indexOf(measure);
|
|
64548
|
+
this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", {
|
|
64549
|
+
formula: newFormulaString,
|
|
64550
|
+
sheetId: measure.computedBy.sheetId,
|
|
64551
|
+
});
|
|
64552
|
+
this.compileCalculatedMeasures(pivotId, pivot.definition.measures);
|
|
64505
64553
|
}
|
|
64506
64554
|
checkSortedColumnInMeasures(definition) {
|
|
64507
64555
|
const measures = definition.measures.map((measure) => measure.id);
|
|
@@ -68029,14 +68077,16 @@ const PERCENT_FORMAT = "0.00%";
|
|
|
68029
68077
|
function withPivotPresentationLayer (PivotClass) {
|
|
68030
68078
|
class PivotPresentationLayer extends PivotClass {
|
|
68031
68079
|
getters;
|
|
68080
|
+
pivotId;
|
|
68032
68081
|
cache = {};
|
|
68033
68082
|
rankAsc = {};
|
|
68034
68083
|
rankDesc = {};
|
|
68035
68084
|
runningTotal = {};
|
|
68036
68085
|
runningTotalInPercent = {};
|
|
68037
|
-
constructor(custom, params) {
|
|
68086
|
+
constructor(pivotId, custom, params) {
|
|
68038
68087
|
super(custom, params);
|
|
68039
68088
|
this.getters = params.getters;
|
|
68089
|
+
this.pivotId = pivotId;
|
|
68040
68090
|
}
|
|
68041
68091
|
markAsDirtyForEvaluation() {
|
|
68042
68092
|
this.cache = {};
|
|
@@ -68086,7 +68136,7 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
68086
68136
|
return handleError(error, measure.aggregator.toUpperCase());
|
|
68087
68137
|
}
|
|
68088
68138
|
}
|
|
68089
|
-
const formula = this.getters.getMeasureCompiledFormula(measure);
|
|
68139
|
+
const formula = this.getters.getMeasureCompiledFormula(this.pivotId, measure);
|
|
68090
68140
|
const getSymbolValue = (symbolName) => {
|
|
68091
68141
|
const { columns, rows } = this.definition;
|
|
68092
68142
|
if (columns.find((col) => col.nameWithGranularity === symbolName)) {
|
|
@@ -68826,7 +68876,7 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
68826
68876
|
const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
|
|
68827
68877
|
if (!(pivotId in this.pivots)) {
|
|
68828
68878
|
const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
|
|
68829
|
-
this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
|
|
68879
|
+
this.pivots[pivotId] = new Pivot(pivotId, this.custom, { definition, getters: this.getters });
|
|
68830
68880
|
}
|
|
68831
68881
|
else if (recreate) {
|
|
68832
68882
|
this.pivots[pivotId].onDefinitionChange(definition);
|
|
@@ -84964,6 +85014,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
|
|
|
84964
85014
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, ClientDisconnectedError, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, LocalTransportService, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
84965
85015
|
|
|
84966
85016
|
|
|
84967
|
-
__info__.version = "18.4.
|
|
84968
|
-
__info__.date = "2026-01-
|
|
84969
|
-
__info__.hash = "
|
|
85017
|
+
__info__.version = "18.4.24";
|
|
85018
|
+
__info__.date = "2026-01-14T10:00:55.867Z";
|
|
85019
|
+
__info__.hash = "0364f56";
|