@odoo/o-spreadsheet 18.3.31 → 18.3.32
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.3.
|
|
6
|
-
* @date
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.3.32
|
|
6
|
+
* @date 2026-01-14T10:00:27.532Z
|
|
7
|
+
* @hash 8d1d321
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -18415,9 +18415,10 @@ function assertDomainLength(domain) {
|
|
|
18415
18415
|
throw new EvaluationError(_t("Function PIVOT takes an even number of arguments."));
|
|
18416
18416
|
}
|
|
18417
18417
|
}
|
|
18418
|
-
function addPivotDependencies(evalContext,
|
|
18418
|
+
function addPivotDependencies(evalContext, pivotId, forMeasures) {
|
|
18419
18419
|
//TODO This function can be very costly when used with PIVOT.VALUE and PIVOT.HEADER
|
|
18420
18420
|
const dependencies = [];
|
|
18421
|
+
const coreDefinition = evalContext.getters.getPivotCoreDefinition(pivotId);
|
|
18421
18422
|
if (coreDefinition.type === "SPREADSHEET" && coreDefinition.dataSet) {
|
|
18422
18423
|
const { sheetId, zone } = coreDefinition.dataSet;
|
|
18423
18424
|
const xc = zoneToXc(zone);
|
|
@@ -18434,8 +18435,7 @@ function addPivotDependencies(evalContext, coreDefinition, forMeasures) {
|
|
|
18434
18435
|
}
|
|
18435
18436
|
for (const measure of forMeasures) {
|
|
18436
18437
|
if (measure.computedBy) {
|
|
18437
|
-
|
|
18438
|
-
dependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
|
|
18438
|
+
dependencies.push(...evalContext.getters.getMeasureFullDependencies(pivotId, measure));
|
|
18439
18439
|
}
|
|
18440
18440
|
}
|
|
18441
18441
|
const originPosition = evalContext.__originCellPosition;
|
|
@@ -18870,7 +18870,7 @@ const PIVOT_VALUE = {
|
|
|
18870
18870
|
assertDomainLength(domainArgs);
|
|
18871
18871
|
const pivot = this.getters.getPivot(pivotId);
|
|
18872
18872
|
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
18873
|
-
addPivotDependencies(this,
|
|
18873
|
+
addPivotDependencies(this, pivotId, coreDefinition.measures.filter((m) => m.id === _measure));
|
|
18874
18874
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
18875
18875
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
18876
18876
|
if (error) {
|
|
@@ -18903,8 +18903,7 @@ const PIVOT_HEADER = {
|
|
|
18903
18903
|
const _pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
18904
18904
|
assertDomainLength(domainArgs);
|
|
18905
18905
|
const pivot = this.getters.getPivot(_pivotId);
|
|
18906
|
-
|
|
18907
|
-
addPivotDependencies(this, coreDefinition, []);
|
|
18906
|
+
addPivotDependencies(this, _pivotId, []);
|
|
18908
18907
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
18909
18908
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
18910
18909
|
if (error) {
|
|
@@ -18958,7 +18957,7 @@ const PIVOT = {
|
|
|
18958
18957
|
const pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
18959
18958
|
const pivot = this.getters.getPivot(pivotId);
|
|
18960
18959
|
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
18961
|
-
addPivotDependencies(this,
|
|
18960
|
+
addPivotDependencies(this, pivotId, coreDefinition.measures);
|
|
18962
18961
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
18963
18962
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
18964
18963
|
if (error) {
|
|
@@ -23230,7 +23229,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
23230
23229
|
}
|
|
23231
23230
|
captureSelection(zone, col, row) {
|
|
23232
23231
|
this.model.selection.capture(this, {
|
|
23233
|
-
cell: { col: col ?? zone.left, row: row ?? zone.
|
|
23232
|
+
cell: { col: col ?? zone.left, row: row ?? zone.top },
|
|
23234
23233
|
zone,
|
|
23235
23234
|
}, {
|
|
23236
23235
|
handleEvent: this.handleEvent.bind(this),
|
|
@@ -47618,6 +47617,12 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
47618
47617
|
case "ACTIVATE_SHEET":
|
|
47619
47618
|
this.isSearchDirty = true;
|
|
47620
47619
|
this.shouldFinalizeUpdateSelection = true;
|
|
47620
|
+
if (this.searchOptions.specificRange) {
|
|
47621
|
+
this.searchOptions.specificRange = {
|
|
47622
|
+
...this.searchOptions.specificRange,
|
|
47623
|
+
sheetId: this.getters.getActiveSheetId(),
|
|
47624
|
+
};
|
|
47625
|
+
}
|
|
47621
47626
|
break;
|
|
47622
47627
|
case "REPLACE_SEARCH":
|
|
47623
47628
|
for (const match of cmd.matches) {
|
|
@@ -48039,9 +48044,20 @@ class FindAndReplacePanel extends owl.Component {
|
|
|
48039
48044
|
const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.dataRange);
|
|
48040
48045
|
this.store.updateSearchOptions({ specificRange });
|
|
48041
48046
|
}
|
|
48047
|
+
get specificRange() {
|
|
48048
|
+
const range = this.store.searchOptions.specificRange;
|
|
48049
|
+
return range ? this.env.model.getters.getRangeString(range, "forceSheetReference") : "";
|
|
48050
|
+
}
|
|
48042
48051
|
get pendingSearch() {
|
|
48043
48052
|
return this.updateSearchContent.isDebouncePending();
|
|
48044
48053
|
}
|
|
48054
|
+
get selectionInputKey() {
|
|
48055
|
+
// Selections input are made to work with objects linked to a sheet id. They store the active sheet id at their creation,
|
|
48056
|
+
// and have specific behaviour linked to it (eg. go back to the initial sheet after confirmation).
|
|
48057
|
+
// We don't want all those behaviors here, so we force the recreation of the component when the active sheet changes.
|
|
48058
|
+
// The only drawback is that the input loses focus when changing sheet.
|
|
48059
|
+
return this.env.model.getters.getActiveSheetId();
|
|
48060
|
+
}
|
|
48045
48061
|
}
|
|
48046
48062
|
|
|
48047
48063
|
css /* scss */ `
|
|
@@ -62743,6 +62759,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
62743
62759
|
"getMeasureCompiledFormula",
|
|
62744
62760
|
"getPivotName",
|
|
62745
62761
|
"isExistingPivot",
|
|
62762
|
+
"getMeasureFullDependencies",
|
|
62746
62763
|
];
|
|
62747
62764
|
nextFormulaId = 1;
|
|
62748
62765
|
pivots = {};
|
|
@@ -62825,7 +62842,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
62825
62842
|
}
|
|
62826
62843
|
case "UPDATE_PIVOT": {
|
|
62827
62844
|
this.history.update("pivots", cmd.pivotId, "definition", this.repairSortedColumn(deepCopy(cmd.pivot)));
|
|
62828
|
-
this.compileCalculatedMeasures(cmd.pivot.measures);
|
|
62845
|
+
this.compileCalculatedMeasures(cmd.pivotId, cmd.pivot.measures);
|
|
62829
62846
|
break;
|
|
62830
62847
|
}
|
|
62831
62848
|
}
|
|
@@ -62843,9 +62860,14 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
62843
62860
|
this.history.update("pivots", pivotId, "definition", newDefinition);
|
|
62844
62861
|
}
|
|
62845
62862
|
}
|
|
62846
|
-
for (const
|
|
62847
|
-
for (const
|
|
62848
|
-
const
|
|
62863
|
+
for (const pivotId in this.compiledMeasureFormulas) {
|
|
62864
|
+
for (const measureId in this.compiledMeasureFormulas[pivotId]) {
|
|
62865
|
+
const measure = this.pivots[pivotId]?.definition.measures.find((m) => m.id === measureId);
|
|
62866
|
+
if (!measure || !measure.computedBy) {
|
|
62867
|
+
continue;
|
|
62868
|
+
}
|
|
62869
|
+
const sheetId = measure.computedBy.sheetId;
|
|
62870
|
+
const compiledFormula = this.compiledMeasureFormulas[pivotId][measureId].formula;
|
|
62849
62871
|
const newDependencies = [];
|
|
62850
62872
|
for (const range of compiledFormula.dependencies) {
|
|
62851
62873
|
const change = applyChange(range);
|
|
@@ -62857,8 +62879,9 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
62857
62879
|
}
|
|
62858
62880
|
}
|
|
62859
62881
|
const newFormulaString = this.getters.getFormulaString(sheetId, compiledFormula.tokens, newDependencies);
|
|
62860
|
-
|
|
62861
|
-
|
|
62882
|
+
const oldFormulaString = measure.computedBy.formula;
|
|
62883
|
+
if (newFormulaString !== oldFormulaString) {
|
|
62884
|
+
this.replaceMeasureFormula(pivotId, measure, newFormulaString);
|
|
62862
62885
|
}
|
|
62863
62886
|
}
|
|
62864
62887
|
}
|
|
@@ -62896,12 +62919,17 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
62896
62919
|
isExistingPivot(pivotId) {
|
|
62897
62920
|
return pivotId in this.pivots;
|
|
62898
62921
|
}
|
|
62899
|
-
getMeasureCompiledFormula(measure) {
|
|
62922
|
+
getMeasureCompiledFormula(pivotId, measure) {
|
|
62900
62923
|
if (!measure.computedBy) {
|
|
62901
62924
|
throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
|
|
62902
62925
|
}
|
|
62903
|
-
|
|
62904
|
-
|
|
62926
|
+
return this.compiledMeasureFormulas[pivotId][measure.id].formula;
|
|
62927
|
+
}
|
|
62928
|
+
getMeasureFullDependencies(pivotId, measure) {
|
|
62929
|
+
if (!measure.computedBy) {
|
|
62930
|
+
throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
|
|
62931
|
+
}
|
|
62932
|
+
return this.compiledMeasureFormulas[pivotId][measure.id].dependencies;
|
|
62905
62933
|
}
|
|
62906
62934
|
// -------------------------------------------------------------------------
|
|
62907
62935
|
// Private
|
|
@@ -62911,18 +62939,42 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
62911
62939
|
definition: this.repairSortedColumn(deepCopy(pivot)),
|
|
62912
62940
|
formulaId,
|
|
62913
62941
|
});
|
|
62914
|
-
this.compileCalculatedMeasures(pivot.measures);
|
|
62942
|
+
this.compileCalculatedMeasures(pivotId, pivot.measures);
|
|
62915
62943
|
this.history.update("formulaIds", formulaId, pivotId);
|
|
62916
62944
|
this.history.update("nextFormulaId", this.nextFormulaId + 1);
|
|
62917
62945
|
}
|
|
62918
|
-
compileCalculatedMeasures(measures) {
|
|
62946
|
+
compileCalculatedMeasures(pivotId, measures) {
|
|
62919
62947
|
for (const measure of measures) {
|
|
62920
62948
|
if (measure.computedBy) {
|
|
62921
|
-
const sheetId = measure.computedBy.sheetId;
|
|
62922
62949
|
const compiledFormula = this.compileMeasureFormula(measure.computedBy.sheetId, measure.computedBy.formula);
|
|
62923
|
-
this.history.update("compiledMeasureFormulas",
|
|
62950
|
+
this.history.update("compiledMeasureFormulas", pivotId, measure.id, "formula", compiledFormula);
|
|
62924
62951
|
}
|
|
62925
62952
|
}
|
|
62953
|
+
for (const measure of measures) {
|
|
62954
|
+
if (measure.computedBy) {
|
|
62955
|
+
const dependencies = this.computeMeasureFullDependencies(pivotId, measure);
|
|
62956
|
+
this.history.update("compiledMeasureFormulas", pivotId, measure.id, "dependencies", dependencies);
|
|
62957
|
+
}
|
|
62958
|
+
}
|
|
62959
|
+
}
|
|
62960
|
+
computeMeasureFullDependencies(pivotId, measure, exploredMeasures = new Set()) {
|
|
62961
|
+
const rangeDependencies = [];
|
|
62962
|
+
const definition = this.getPivotCoreDefinition(pivotId);
|
|
62963
|
+
const formula = this.getMeasureCompiledFormula(pivotId, measure);
|
|
62964
|
+
exploredMeasures.add(measure.id);
|
|
62965
|
+
for (const token of formula.tokens) {
|
|
62966
|
+
if (token.type !== "SYMBOL") {
|
|
62967
|
+
continue;
|
|
62968
|
+
}
|
|
62969
|
+
const otherMeasure = definition.measures.find((measureCandidate) => getCanonicalSymbolName(measureCandidate.id) === token.value &&
|
|
62970
|
+
measure.id !== measureCandidate.id);
|
|
62971
|
+
if (!otherMeasure || exploredMeasures.has(otherMeasure.id) || !otherMeasure.computedBy) {
|
|
62972
|
+
continue;
|
|
62973
|
+
}
|
|
62974
|
+
rangeDependencies.push(...this.computeMeasureFullDependencies(pivotId, otherMeasure, exploredMeasures));
|
|
62975
|
+
}
|
|
62976
|
+
rangeDependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
|
|
62977
|
+
return rangeDependencies;
|
|
62926
62978
|
}
|
|
62927
62979
|
insertPivot(position, formulaId, table) {
|
|
62928
62980
|
this.resizeSheet(position.sheetId, position, table);
|
|
@@ -62982,21 +63034,17 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
62982
63034
|
dependencies: rangeDependencies,
|
|
62983
63035
|
};
|
|
62984
63036
|
}
|
|
62985
|
-
replaceMeasureFormula(
|
|
62986
|
-
|
|
62987
|
-
|
|
62988
|
-
|
|
62989
|
-
const pivot = this.pivots[pivotId];
|
|
62990
|
-
if (!pivot) {
|
|
62991
|
-
continue;
|
|
62992
|
-
}
|
|
62993
|
-
for (const measure of pivot.definition.measures) {
|
|
62994
|
-
if (measure.computedBy?.formula === formulaString) {
|
|
62995
|
-
const measureIndex = pivot.definition.measures.indexOf(measure);
|
|
62996
|
-
this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", { formula: newFormulaString, sheetId });
|
|
62997
|
-
}
|
|
62998
|
-
}
|
|
63037
|
+
replaceMeasureFormula(pivotId, measure, newFormulaString) {
|
|
63038
|
+
const pivot = this.pivots[pivotId];
|
|
63039
|
+
if (!pivot) {
|
|
63040
|
+
return;
|
|
62999
63041
|
}
|
|
63042
|
+
const measureIndex = pivot.definition.measures.indexOf(measure);
|
|
63043
|
+
this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", {
|
|
63044
|
+
formula: newFormulaString,
|
|
63045
|
+
sheetId: measure.computedBy.sheetId,
|
|
63046
|
+
});
|
|
63047
|
+
this.compileCalculatedMeasures(pivotId, pivot.definition.measures);
|
|
63000
63048
|
}
|
|
63001
63049
|
checkSortedColumnInMeasures(definition) {
|
|
63002
63050
|
definition = this.repairSortedColumn(definition);
|
|
@@ -66286,14 +66334,16 @@ const PERCENT_FORMAT = "0.00%";
|
|
|
66286
66334
|
function withPivotPresentationLayer (PivotClass) {
|
|
66287
66335
|
class PivotPresentationLayer extends PivotClass {
|
|
66288
66336
|
getters;
|
|
66337
|
+
pivotId;
|
|
66289
66338
|
cache = {};
|
|
66290
66339
|
rankAsc = {};
|
|
66291
66340
|
rankDesc = {};
|
|
66292
66341
|
runningTotal = {};
|
|
66293
66342
|
runningTotalInPercent = {};
|
|
66294
|
-
constructor(custom, params) {
|
|
66343
|
+
constructor(pivotId, custom, params) {
|
|
66295
66344
|
super(custom, params);
|
|
66296
66345
|
this.getters = params.getters;
|
|
66346
|
+
this.pivotId = pivotId;
|
|
66297
66347
|
}
|
|
66298
66348
|
markAsDirtyForEvaluation() {
|
|
66299
66349
|
this.cache = {};
|
|
@@ -66343,7 +66393,7 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
66343
66393
|
return handleError(error, measure.aggregator.toUpperCase());
|
|
66344
66394
|
}
|
|
66345
66395
|
}
|
|
66346
|
-
const formula = this.getters.getMeasureCompiledFormula(measure);
|
|
66396
|
+
const formula = this.getters.getMeasureCompiledFormula(this.pivotId, measure);
|
|
66347
66397
|
const getSymbolValue = (symbolName) => {
|
|
66348
66398
|
const { columns, rows } = this.definition;
|
|
66349
66399
|
if (columns.find((col) => col.nameWithGranularity === symbolName)) {
|
|
@@ -67071,7 +67121,7 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
67071
67121
|
const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
|
|
67072
67122
|
if (!(pivotId in this.pivots)) {
|
|
67073
67123
|
const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
|
|
67074
|
-
this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
|
|
67124
|
+
this.pivots[pivotId] = new Pivot(pivotId, this.custom, { definition, getters: this.getters });
|
|
67075
67125
|
}
|
|
67076
67126
|
else if (recreate) {
|
|
67077
67127
|
this.pivots[pivotId].onDefinitionChange(definition);
|
|
@@ -81114,6 +81164,6 @@ exports.tokenColors = tokenColors;
|
|
|
81114
81164
|
exports.tokenize = tokenize;
|
|
81115
81165
|
|
|
81116
81166
|
|
|
81117
|
-
__info__.version = "18.3.
|
|
81118
|
-
__info__.date = "
|
|
81119
|
-
__info__.hash = "
|
|
81167
|
+
__info__.version = "18.3.32";
|
|
81168
|
+
__info__.date = "2026-01-14T10:00:27.532Z";
|
|
81169
|
+
__info__.hash = "8d1d321";
|
package/dist/o-spreadsheet.d.ts
CHANGED
|
@@ -5074,14 +5074,18 @@ interface Pivot$1 {
|
|
|
5074
5074
|
definition: PivotCoreDefinition;
|
|
5075
5075
|
formulaId: string;
|
|
5076
5076
|
}
|
|
5077
|
+
interface MeasureState {
|
|
5078
|
+
formula: RangeCompiledFormula;
|
|
5079
|
+
dependencies: Range[];
|
|
5080
|
+
}
|
|
5077
5081
|
interface CoreState {
|
|
5078
5082
|
nextFormulaId: number;
|
|
5079
5083
|
pivots: Record<UID, Pivot$1 | undefined>;
|
|
5080
5084
|
formulaIds: Record<UID, string | undefined>;
|
|
5081
|
-
compiledMeasureFormulas: Record<UID, Record<string,
|
|
5085
|
+
compiledMeasureFormulas: Record<UID, Record<string, MeasureState | undefined>>;
|
|
5082
5086
|
}
|
|
5083
5087
|
declare class PivotCorePlugin extends CorePlugin<CoreState> implements CoreState {
|
|
5084
|
-
static getters: readonly ["getPivotCoreDefinition", "getPivotDisplayName", "getPivotId", "getPivotFormulaId", "getPivotIds", "getMeasureCompiledFormula", "getPivotName", "isExistingPivot"];
|
|
5088
|
+
static getters: readonly ["getPivotCoreDefinition", "getPivotDisplayName", "getPivotId", "getPivotFormulaId", "getPivotIds", "getMeasureCompiledFormula", "getPivotName", "isExistingPivot", "getMeasureFullDependencies"];
|
|
5085
5089
|
readonly nextFormulaId: number;
|
|
5086
5090
|
readonly pivots: {
|
|
5087
5091
|
[pivotId: UID]: Pivot$1 | undefined;
|
|
@@ -5089,7 +5093,7 @@ declare class PivotCorePlugin extends CorePlugin<CoreState> implements CoreState
|
|
|
5089
5093
|
readonly formulaIds: {
|
|
5090
5094
|
[formulaId: UID]: UID | undefined;
|
|
5091
5095
|
};
|
|
5092
|
-
readonly compiledMeasureFormulas: Record<UID, Record<string,
|
|
5096
|
+
readonly compiledMeasureFormulas: Record<UID, Record<string, MeasureState>>;
|
|
5093
5097
|
allowDispatch(cmd: CoreCommand): CommandResult | CommandResult[];
|
|
5094
5098
|
handle(cmd: CoreCommand): void;
|
|
5095
5099
|
adaptRanges(applyChange: ApplyRangeChange): void;
|
|
@@ -5108,9 +5112,11 @@ declare class PivotCorePlugin extends CorePlugin<CoreState> implements CoreState
|
|
|
5108
5112
|
getPivotFormulaId(pivotId: UID): string;
|
|
5109
5113
|
getPivotIds(): UID[];
|
|
5110
5114
|
isExistingPivot(pivotId: UID): boolean;
|
|
5111
|
-
getMeasureCompiledFormula(measure: PivotCoreMeasure): RangeCompiledFormula;
|
|
5115
|
+
getMeasureCompiledFormula(pivotId: UID, measure: PivotCoreMeasure): RangeCompiledFormula;
|
|
5116
|
+
getMeasureFullDependencies(pivotId: UID, measure: PivotCoreMeasure): Range[];
|
|
5112
5117
|
private addPivot;
|
|
5113
5118
|
private compileCalculatedMeasures;
|
|
5119
|
+
private computeMeasureFullDependencies;
|
|
5114
5120
|
private insertPivot;
|
|
5115
5121
|
private resizeSheet;
|
|
5116
5122
|
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.3.
|
|
6
|
-
* @date
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.3.32
|
|
6
|
+
* @date 2026-01-14T10:00:27.532Z
|
|
7
|
+
* @hash 8d1d321
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -18413,9 +18413,10 @@ function assertDomainLength(domain) {
|
|
|
18413
18413
|
throw new EvaluationError(_t("Function PIVOT takes an even number of arguments."));
|
|
18414
18414
|
}
|
|
18415
18415
|
}
|
|
18416
|
-
function addPivotDependencies(evalContext,
|
|
18416
|
+
function addPivotDependencies(evalContext, pivotId, forMeasures) {
|
|
18417
18417
|
//TODO This function can be very costly when used with PIVOT.VALUE and PIVOT.HEADER
|
|
18418
18418
|
const dependencies = [];
|
|
18419
|
+
const coreDefinition = evalContext.getters.getPivotCoreDefinition(pivotId);
|
|
18419
18420
|
if (coreDefinition.type === "SPREADSHEET" && coreDefinition.dataSet) {
|
|
18420
18421
|
const { sheetId, zone } = coreDefinition.dataSet;
|
|
18421
18422
|
const xc = zoneToXc(zone);
|
|
@@ -18432,8 +18433,7 @@ function addPivotDependencies(evalContext, coreDefinition, forMeasures) {
|
|
|
18432
18433
|
}
|
|
18433
18434
|
for (const measure of forMeasures) {
|
|
18434
18435
|
if (measure.computedBy) {
|
|
18435
|
-
|
|
18436
|
-
dependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
|
|
18436
|
+
dependencies.push(...evalContext.getters.getMeasureFullDependencies(pivotId, measure));
|
|
18437
18437
|
}
|
|
18438
18438
|
}
|
|
18439
18439
|
const originPosition = evalContext.__originCellPosition;
|
|
@@ -18868,7 +18868,7 @@ const PIVOT_VALUE = {
|
|
|
18868
18868
|
assertDomainLength(domainArgs);
|
|
18869
18869
|
const pivot = this.getters.getPivot(pivotId);
|
|
18870
18870
|
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
18871
|
-
addPivotDependencies(this,
|
|
18871
|
+
addPivotDependencies(this, pivotId, coreDefinition.measures.filter((m) => m.id === _measure));
|
|
18872
18872
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
18873
18873
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
18874
18874
|
if (error) {
|
|
@@ -18901,8 +18901,7 @@ const PIVOT_HEADER = {
|
|
|
18901
18901
|
const _pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
18902
18902
|
assertDomainLength(domainArgs);
|
|
18903
18903
|
const pivot = this.getters.getPivot(_pivotId);
|
|
18904
|
-
|
|
18905
|
-
addPivotDependencies(this, coreDefinition, []);
|
|
18904
|
+
addPivotDependencies(this, _pivotId, []);
|
|
18906
18905
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
18907
18906
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
18908
18907
|
if (error) {
|
|
@@ -18956,7 +18955,7 @@ const PIVOT = {
|
|
|
18956
18955
|
const pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
18957
18956
|
const pivot = this.getters.getPivot(pivotId);
|
|
18958
18957
|
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
18959
|
-
addPivotDependencies(this,
|
|
18958
|
+
addPivotDependencies(this, pivotId, coreDefinition.measures);
|
|
18960
18959
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
18961
18960
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
18962
18961
|
if (error) {
|
|
@@ -23228,7 +23227,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
23228
23227
|
}
|
|
23229
23228
|
captureSelection(zone, col, row) {
|
|
23230
23229
|
this.model.selection.capture(this, {
|
|
23231
|
-
cell: { col: col ?? zone.left, row: row ?? zone.
|
|
23230
|
+
cell: { col: col ?? zone.left, row: row ?? zone.top },
|
|
23232
23231
|
zone,
|
|
23233
23232
|
}, {
|
|
23234
23233
|
handleEvent: this.handleEvent.bind(this),
|
|
@@ -47616,6 +47615,12 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
47616
47615
|
case "ACTIVATE_SHEET":
|
|
47617
47616
|
this.isSearchDirty = true;
|
|
47618
47617
|
this.shouldFinalizeUpdateSelection = true;
|
|
47618
|
+
if (this.searchOptions.specificRange) {
|
|
47619
|
+
this.searchOptions.specificRange = {
|
|
47620
|
+
...this.searchOptions.specificRange,
|
|
47621
|
+
sheetId: this.getters.getActiveSheetId(),
|
|
47622
|
+
};
|
|
47623
|
+
}
|
|
47619
47624
|
break;
|
|
47620
47625
|
case "REPLACE_SEARCH":
|
|
47621
47626
|
for (const match of cmd.matches) {
|
|
@@ -48037,9 +48042,20 @@ class FindAndReplacePanel extends Component {
|
|
|
48037
48042
|
const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.dataRange);
|
|
48038
48043
|
this.store.updateSearchOptions({ specificRange });
|
|
48039
48044
|
}
|
|
48045
|
+
get specificRange() {
|
|
48046
|
+
const range = this.store.searchOptions.specificRange;
|
|
48047
|
+
return range ? this.env.model.getters.getRangeString(range, "forceSheetReference") : "";
|
|
48048
|
+
}
|
|
48040
48049
|
get pendingSearch() {
|
|
48041
48050
|
return this.updateSearchContent.isDebouncePending();
|
|
48042
48051
|
}
|
|
48052
|
+
get selectionInputKey() {
|
|
48053
|
+
// Selections input are made to work with objects linked to a sheet id. They store the active sheet id at their creation,
|
|
48054
|
+
// and have specific behaviour linked to it (eg. go back to the initial sheet after confirmation).
|
|
48055
|
+
// We don't want all those behaviors here, so we force the recreation of the component when the active sheet changes.
|
|
48056
|
+
// The only drawback is that the input loses focus when changing sheet.
|
|
48057
|
+
return this.env.model.getters.getActiveSheetId();
|
|
48058
|
+
}
|
|
48043
48059
|
}
|
|
48044
48060
|
|
|
48045
48061
|
css /* scss */ `
|
|
@@ -62741,6 +62757,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
62741
62757
|
"getMeasureCompiledFormula",
|
|
62742
62758
|
"getPivotName",
|
|
62743
62759
|
"isExistingPivot",
|
|
62760
|
+
"getMeasureFullDependencies",
|
|
62744
62761
|
];
|
|
62745
62762
|
nextFormulaId = 1;
|
|
62746
62763
|
pivots = {};
|
|
@@ -62823,7 +62840,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
62823
62840
|
}
|
|
62824
62841
|
case "UPDATE_PIVOT": {
|
|
62825
62842
|
this.history.update("pivots", cmd.pivotId, "definition", this.repairSortedColumn(deepCopy(cmd.pivot)));
|
|
62826
|
-
this.compileCalculatedMeasures(cmd.pivot.measures);
|
|
62843
|
+
this.compileCalculatedMeasures(cmd.pivotId, cmd.pivot.measures);
|
|
62827
62844
|
break;
|
|
62828
62845
|
}
|
|
62829
62846
|
}
|
|
@@ -62841,9 +62858,14 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
62841
62858
|
this.history.update("pivots", pivotId, "definition", newDefinition);
|
|
62842
62859
|
}
|
|
62843
62860
|
}
|
|
62844
|
-
for (const
|
|
62845
|
-
for (const
|
|
62846
|
-
const
|
|
62861
|
+
for (const pivotId in this.compiledMeasureFormulas) {
|
|
62862
|
+
for (const measureId in this.compiledMeasureFormulas[pivotId]) {
|
|
62863
|
+
const measure = this.pivots[pivotId]?.definition.measures.find((m) => m.id === measureId);
|
|
62864
|
+
if (!measure || !measure.computedBy) {
|
|
62865
|
+
continue;
|
|
62866
|
+
}
|
|
62867
|
+
const sheetId = measure.computedBy.sheetId;
|
|
62868
|
+
const compiledFormula = this.compiledMeasureFormulas[pivotId][measureId].formula;
|
|
62847
62869
|
const newDependencies = [];
|
|
62848
62870
|
for (const range of compiledFormula.dependencies) {
|
|
62849
62871
|
const change = applyChange(range);
|
|
@@ -62855,8 +62877,9 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
62855
62877
|
}
|
|
62856
62878
|
}
|
|
62857
62879
|
const newFormulaString = this.getters.getFormulaString(sheetId, compiledFormula.tokens, newDependencies);
|
|
62858
|
-
|
|
62859
|
-
|
|
62880
|
+
const oldFormulaString = measure.computedBy.formula;
|
|
62881
|
+
if (newFormulaString !== oldFormulaString) {
|
|
62882
|
+
this.replaceMeasureFormula(pivotId, measure, newFormulaString);
|
|
62860
62883
|
}
|
|
62861
62884
|
}
|
|
62862
62885
|
}
|
|
@@ -62894,12 +62917,17 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
62894
62917
|
isExistingPivot(pivotId) {
|
|
62895
62918
|
return pivotId in this.pivots;
|
|
62896
62919
|
}
|
|
62897
|
-
getMeasureCompiledFormula(measure) {
|
|
62920
|
+
getMeasureCompiledFormula(pivotId, measure) {
|
|
62898
62921
|
if (!measure.computedBy) {
|
|
62899
62922
|
throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
|
|
62900
62923
|
}
|
|
62901
|
-
|
|
62902
|
-
|
|
62924
|
+
return this.compiledMeasureFormulas[pivotId][measure.id].formula;
|
|
62925
|
+
}
|
|
62926
|
+
getMeasureFullDependencies(pivotId, measure) {
|
|
62927
|
+
if (!measure.computedBy) {
|
|
62928
|
+
throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
|
|
62929
|
+
}
|
|
62930
|
+
return this.compiledMeasureFormulas[pivotId][measure.id].dependencies;
|
|
62903
62931
|
}
|
|
62904
62932
|
// -------------------------------------------------------------------------
|
|
62905
62933
|
// Private
|
|
@@ -62909,18 +62937,42 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
62909
62937
|
definition: this.repairSortedColumn(deepCopy(pivot)),
|
|
62910
62938
|
formulaId,
|
|
62911
62939
|
});
|
|
62912
|
-
this.compileCalculatedMeasures(pivot.measures);
|
|
62940
|
+
this.compileCalculatedMeasures(pivotId, pivot.measures);
|
|
62913
62941
|
this.history.update("formulaIds", formulaId, pivotId);
|
|
62914
62942
|
this.history.update("nextFormulaId", this.nextFormulaId + 1);
|
|
62915
62943
|
}
|
|
62916
|
-
compileCalculatedMeasures(measures) {
|
|
62944
|
+
compileCalculatedMeasures(pivotId, measures) {
|
|
62917
62945
|
for (const measure of measures) {
|
|
62918
62946
|
if (measure.computedBy) {
|
|
62919
|
-
const sheetId = measure.computedBy.sheetId;
|
|
62920
62947
|
const compiledFormula = this.compileMeasureFormula(measure.computedBy.sheetId, measure.computedBy.formula);
|
|
62921
|
-
this.history.update("compiledMeasureFormulas",
|
|
62948
|
+
this.history.update("compiledMeasureFormulas", pivotId, measure.id, "formula", compiledFormula);
|
|
62922
62949
|
}
|
|
62923
62950
|
}
|
|
62951
|
+
for (const measure of measures) {
|
|
62952
|
+
if (measure.computedBy) {
|
|
62953
|
+
const dependencies = this.computeMeasureFullDependencies(pivotId, measure);
|
|
62954
|
+
this.history.update("compiledMeasureFormulas", pivotId, measure.id, "dependencies", dependencies);
|
|
62955
|
+
}
|
|
62956
|
+
}
|
|
62957
|
+
}
|
|
62958
|
+
computeMeasureFullDependencies(pivotId, measure, exploredMeasures = new Set()) {
|
|
62959
|
+
const rangeDependencies = [];
|
|
62960
|
+
const definition = this.getPivotCoreDefinition(pivotId);
|
|
62961
|
+
const formula = this.getMeasureCompiledFormula(pivotId, measure);
|
|
62962
|
+
exploredMeasures.add(measure.id);
|
|
62963
|
+
for (const token of formula.tokens) {
|
|
62964
|
+
if (token.type !== "SYMBOL") {
|
|
62965
|
+
continue;
|
|
62966
|
+
}
|
|
62967
|
+
const otherMeasure = definition.measures.find((measureCandidate) => getCanonicalSymbolName(measureCandidate.id) === token.value &&
|
|
62968
|
+
measure.id !== measureCandidate.id);
|
|
62969
|
+
if (!otherMeasure || exploredMeasures.has(otherMeasure.id) || !otherMeasure.computedBy) {
|
|
62970
|
+
continue;
|
|
62971
|
+
}
|
|
62972
|
+
rangeDependencies.push(...this.computeMeasureFullDependencies(pivotId, otherMeasure, exploredMeasures));
|
|
62973
|
+
}
|
|
62974
|
+
rangeDependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
|
|
62975
|
+
return rangeDependencies;
|
|
62924
62976
|
}
|
|
62925
62977
|
insertPivot(position, formulaId, table) {
|
|
62926
62978
|
this.resizeSheet(position.sheetId, position, table);
|
|
@@ -62980,21 +63032,17 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
62980
63032
|
dependencies: rangeDependencies,
|
|
62981
63033
|
};
|
|
62982
63034
|
}
|
|
62983
|
-
replaceMeasureFormula(
|
|
62984
|
-
|
|
62985
|
-
|
|
62986
|
-
|
|
62987
|
-
const pivot = this.pivots[pivotId];
|
|
62988
|
-
if (!pivot) {
|
|
62989
|
-
continue;
|
|
62990
|
-
}
|
|
62991
|
-
for (const measure of pivot.definition.measures) {
|
|
62992
|
-
if (measure.computedBy?.formula === formulaString) {
|
|
62993
|
-
const measureIndex = pivot.definition.measures.indexOf(measure);
|
|
62994
|
-
this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", { formula: newFormulaString, sheetId });
|
|
62995
|
-
}
|
|
62996
|
-
}
|
|
63035
|
+
replaceMeasureFormula(pivotId, measure, newFormulaString) {
|
|
63036
|
+
const pivot = this.pivots[pivotId];
|
|
63037
|
+
if (!pivot) {
|
|
63038
|
+
return;
|
|
62997
63039
|
}
|
|
63040
|
+
const measureIndex = pivot.definition.measures.indexOf(measure);
|
|
63041
|
+
this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", {
|
|
63042
|
+
formula: newFormulaString,
|
|
63043
|
+
sheetId: measure.computedBy.sheetId,
|
|
63044
|
+
});
|
|
63045
|
+
this.compileCalculatedMeasures(pivotId, pivot.definition.measures);
|
|
62998
63046
|
}
|
|
62999
63047
|
checkSortedColumnInMeasures(definition) {
|
|
63000
63048
|
definition = this.repairSortedColumn(definition);
|
|
@@ -66284,14 +66332,16 @@ const PERCENT_FORMAT = "0.00%";
|
|
|
66284
66332
|
function withPivotPresentationLayer (PivotClass) {
|
|
66285
66333
|
class PivotPresentationLayer extends PivotClass {
|
|
66286
66334
|
getters;
|
|
66335
|
+
pivotId;
|
|
66287
66336
|
cache = {};
|
|
66288
66337
|
rankAsc = {};
|
|
66289
66338
|
rankDesc = {};
|
|
66290
66339
|
runningTotal = {};
|
|
66291
66340
|
runningTotalInPercent = {};
|
|
66292
|
-
constructor(custom, params) {
|
|
66341
|
+
constructor(pivotId, custom, params) {
|
|
66293
66342
|
super(custom, params);
|
|
66294
66343
|
this.getters = params.getters;
|
|
66344
|
+
this.pivotId = pivotId;
|
|
66295
66345
|
}
|
|
66296
66346
|
markAsDirtyForEvaluation() {
|
|
66297
66347
|
this.cache = {};
|
|
@@ -66341,7 +66391,7 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
66341
66391
|
return handleError(error, measure.aggregator.toUpperCase());
|
|
66342
66392
|
}
|
|
66343
66393
|
}
|
|
66344
|
-
const formula = this.getters.getMeasureCompiledFormula(measure);
|
|
66394
|
+
const formula = this.getters.getMeasureCompiledFormula(this.pivotId, measure);
|
|
66345
66395
|
const getSymbolValue = (symbolName) => {
|
|
66346
66396
|
const { columns, rows } = this.definition;
|
|
66347
66397
|
if (columns.find((col) => col.nameWithGranularity === symbolName)) {
|
|
@@ -67069,7 +67119,7 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
67069
67119
|
const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
|
|
67070
67120
|
if (!(pivotId in this.pivots)) {
|
|
67071
67121
|
const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
|
|
67072
|
-
this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
|
|
67122
|
+
this.pivots[pivotId] = new Pivot(pivotId, this.custom, { definition, getters: this.getters });
|
|
67073
67123
|
}
|
|
67074
67124
|
else if (recreate) {
|
|
67075
67125
|
this.pivots[pivotId].onDefinitionChange(definition);
|
|
@@ -81066,6 +81116,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
|
|
|
81066
81116
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, 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 };
|
|
81067
81117
|
|
|
81068
81118
|
|
|
81069
|
-
__info__.version = "18.3.
|
|
81070
|
-
__info__.date = "
|
|
81071
|
-
__info__.hash = "
|
|
81119
|
+
__info__.version = "18.3.32";
|
|
81120
|
+
__info__.date = "2026-01-14T10:00:27.532Z";
|
|
81121
|
+
__info__.hash = "8d1d321";
|