@odoo/o-spreadsheet 19.0.16 → 19.0.17
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 +6 -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 19.0.
|
|
6
|
-
* @date 2026-01-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.0.17
|
|
6
|
+
* @date 2026-01-14T10:01:24.044Z
|
|
7
|
+
* @hash 2165bad
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -20100,9 +20100,10 @@ function assertDomainLength(domain) {
|
|
|
20100
20100
|
throw new EvaluationError(_t("Function PIVOT takes an even number of arguments."));
|
|
20101
20101
|
}
|
|
20102
20102
|
}
|
|
20103
|
-
function addPivotDependencies(evalContext,
|
|
20103
|
+
function addPivotDependencies(evalContext, pivotId, forMeasures) {
|
|
20104
20104
|
//TODO This function can be very costly when used with PIVOT.VALUE and PIVOT.HEADER
|
|
20105
20105
|
const dependencies = [];
|
|
20106
|
+
const coreDefinition = evalContext.getters.getPivotCoreDefinition(pivotId);
|
|
20106
20107
|
if (coreDefinition.type === "SPREADSHEET" && coreDefinition.dataSet) {
|
|
20107
20108
|
const { sheetId, zone } = coreDefinition.dataSet;
|
|
20108
20109
|
const xc = zoneToXc(zone);
|
|
@@ -20119,8 +20120,7 @@ function addPivotDependencies(evalContext, coreDefinition, forMeasures) {
|
|
|
20119
20120
|
}
|
|
20120
20121
|
for (const measure of forMeasures) {
|
|
20121
20122
|
if (measure.computedBy) {
|
|
20122
|
-
|
|
20123
|
-
dependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
|
|
20123
|
+
dependencies.push(...evalContext.getters.getMeasureFullDependencies(pivotId, measure));
|
|
20124
20124
|
}
|
|
20125
20125
|
}
|
|
20126
20126
|
const originPosition = evalContext.__originCellPosition;
|
|
@@ -20617,7 +20617,7 @@ const PIVOT_VALUE = {
|
|
|
20617
20617
|
assertDomainLength(domainArgs);
|
|
20618
20618
|
const pivot = this.getters.getPivot(pivotId);
|
|
20619
20619
|
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
20620
|
-
addPivotDependencies(this,
|
|
20620
|
+
addPivotDependencies(this, pivotId, coreDefinition.measures.filter((m) => m.id === _measure));
|
|
20621
20621
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
20622
20622
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
20623
20623
|
if (error) {
|
|
@@ -20650,8 +20650,7 @@ const PIVOT_HEADER = {
|
|
|
20650
20650
|
const _pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
20651
20651
|
assertDomainLength(domainArgs);
|
|
20652
20652
|
const pivot = this.getters.getPivot(_pivotId);
|
|
20653
|
-
|
|
20654
|
-
addPivotDependencies(this, coreDefinition, []);
|
|
20653
|
+
addPivotDependencies(this, _pivotId, []);
|
|
20655
20654
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
20656
20655
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
20657
20656
|
if (error) {
|
|
@@ -20709,7 +20708,7 @@ const PIVOT = {
|
|
|
20709
20708
|
const pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
20710
20709
|
const pivot = this.getters.getPivot(pivotId);
|
|
20711
20710
|
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
20712
|
-
addPivotDependencies(this,
|
|
20711
|
+
addPivotDependencies(this, pivotId, coreDefinition.measures);
|
|
20713
20712
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
20714
20713
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
20715
20714
|
if (error) {
|
|
@@ -35484,7 +35483,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
35484
35483
|
}
|
|
35485
35484
|
captureSelection(zone, col, row) {
|
|
35486
35485
|
this.model.selection.capture(this, {
|
|
35487
|
-
cell: { col: col ?? zone.left, row: row ?? zone.
|
|
35486
|
+
cell: { col: col ?? zone.left, row: row ?? zone.top },
|
|
35488
35487
|
zone,
|
|
35489
35488
|
}, {
|
|
35490
35489
|
handleEvent: this.handleEvent.bind(this),
|
|
@@ -57877,6 +57876,12 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
57877
57876
|
case "ACTIVATE_SHEET":
|
|
57878
57877
|
this.isSearchDirty = true;
|
|
57879
57878
|
this.shouldFinalizeUpdateSelection = true;
|
|
57879
|
+
if (this.searchOptions.specificRange) {
|
|
57880
|
+
this.searchOptions.specificRange = {
|
|
57881
|
+
...this.searchOptions.specificRange,
|
|
57882
|
+
sheetId: this.getters.getActiveSheetId(),
|
|
57883
|
+
};
|
|
57884
|
+
}
|
|
57880
57885
|
break;
|
|
57881
57886
|
case "REPLACE_SEARCH":
|
|
57882
57887
|
for (const match of cmd.matches) {
|
|
@@ -58296,9 +58301,20 @@ class FindAndReplacePanel extends owl.Component {
|
|
|
58296
58301
|
const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.dataRange);
|
|
58297
58302
|
this.store.updateSearchOptions({ specificRange });
|
|
58298
58303
|
}
|
|
58304
|
+
get specificRange() {
|
|
58305
|
+
const range = this.store.searchOptions.specificRange;
|
|
58306
|
+
return range ? this.env.model.getters.getRangeString(range, "forceSheetReference") : "";
|
|
58307
|
+
}
|
|
58299
58308
|
get pendingSearch() {
|
|
58300
58309
|
return this.updateSearchContent.isDebouncePending();
|
|
58301
58310
|
}
|
|
58311
|
+
get selectionInputKey() {
|
|
58312
|
+
// Selections input are made to work with objects linked to a sheet id. They store the active sheet id at their creation,
|
|
58313
|
+
// and have specific behaviour linked to it (eg. go back to the initial sheet after confirmation).
|
|
58314
|
+
// We don't want all those behaviors here, so we force the recreation of the component when the active sheet changes.
|
|
58315
|
+
// The only drawback is that the input loses focus when changing sheet.
|
|
58316
|
+
return this.env.model.getters.getActiveSheetId();
|
|
58317
|
+
}
|
|
58302
58318
|
}
|
|
58303
58319
|
|
|
58304
58320
|
css /* scss */ `
|
|
@@ -67608,6 +67624,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
67608
67624
|
"getMeasureCompiledFormula",
|
|
67609
67625
|
"getPivotName",
|
|
67610
67626
|
"isExistingPivot",
|
|
67627
|
+
"getMeasureFullDependencies",
|
|
67611
67628
|
];
|
|
67612
67629
|
nextFormulaId = 1;
|
|
67613
67630
|
pivots = {};
|
|
@@ -67690,7 +67707,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
67690
67707
|
}
|
|
67691
67708
|
case "UPDATE_PIVOT": {
|
|
67692
67709
|
this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
|
|
67693
|
-
this.compileCalculatedMeasures(cmd.pivot.measures);
|
|
67710
|
+
this.compileCalculatedMeasures(cmd.pivotId, cmd.pivot.measures);
|
|
67694
67711
|
break;
|
|
67695
67712
|
}
|
|
67696
67713
|
}
|
|
@@ -67708,9 +67725,14 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
67708
67725
|
this.history.update("pivots", pivotId, "definition", newDefinition);
|
|
67709
67726
|
}
|
|
67710
67727
|
}
|
|
67711
|
-
for (const
|
|
67712
|
-
for (const
|
|
67713
|
-
const
|
|
67728
|
+
for (const pivotId in this.compiledMeasureFormulas) {
|
|
67729
|
+
for (const measureId in this.compiledMeasureFormulas[pivotId]) {
|
|
67730
|
+
const measure = this.pivots[pivotId]?.definition.measures.find((m) => m.id === measureId);
|
|
67731
|
+
if (!measure || !measure.computedBy) {
|
|
67732
|
+
continue;
|
|
67733
|
+
}
|
|
67734
|
+
const sheetId = measure.computedBy.sheetId;
|
|
67735
|
+
const compiledFormula = this.compiledMeasureFormulas[pivotId][measureId].formula;
|
|
67714
67736
|
const newDependencies = [];
|
|
67715
67737
|
for (const range of compiledFormula.dependencies) {
|
|
67716
67738
|
const change = applyChange(range);
|
|
@@ -67722,8 +67744,9 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
67722
67744
|
}
|
|
67723
67745
|
}
|
|
67724
67746
|
const newFormulaString = this.getters.getFormulaString(sheetId, compiledFormula.tokens, newDependencies);
|
|
67725
|
-
|
|
67726
|
-
|
|
67747
|
+
const oldFormulaString = measure.computedBy.formula;
|
|
67748
|
+
if (newFormulaString !== oldFormulaString) {
|
|
67749
|
+
this.replaceMeasureFormula(pivotId, measure, newFormulaString);
|
|
67727
67750
|
}
|
|
67728
67751
|
}
|
|
67729
67752
|
}
|
|
@@ -67761,30 +67784,59 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
67761
67784
|
isExistingPivot(pivotId) {
|
|
67762
67785
|
return pivotId in this.pivots;
|
|
67763
67786
|
}
|
|
67764
|
-
getMeasureCompiledFormula(measure) {
|
|
67787
|
+
getMeasureCompiledFormula(pivotId, measure) {
|
|
67765
67788
|
if (!measure.computedBy) {
|
|
67766
67789
|
throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
|
|
67767
67790
|
}
|
|
67768
|
-
|
|
67769
|
-
|
|
67791
|
+
return this.compiledMeasureFormulas[pivotId][measure.id].formula;
|
|
67792
|
+
}
|
|
67793
|
+
getMeasureFullDependencies(pivotId, measure) {
|
|
67794
|
+
if (!measure.computedBy) {
|
|
67795
|
+
throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
|
|
67796
|
+
}
|
|
67797
|
+
return this.compiledMeasureFormulas[pivotId][measure.id].dependencies;
|
|
67770
67798
|
}
|
|
67771
67799
|
// -------------------------------------------------------------------------
|
|
67772
67800
|
// Private
|
|
67773
67801
|
// -------------------------------------------------------------------------
|
|
67774
67802
|
addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
|
|
67775
67803
|
this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
|
|
67776
|
-
this.compileCalculatedMeasures(pivot.measures);
|
|
67804
|
+
this.compileCalculatedMeasures(pivotId, pivot.measures);
|
|
67777
67805
|
this.history.update("formulaIds", formulaId, pivotId);
|
|
67778
67806
|
this.history.update("nextFormulaId", this.nextFormulaId + 1);
|
|
67779
67807
|
}
|
|
67780
|
-
compileCalculatedMeasures(measures) {
|
|
67808
|
+
compileCalculatedMeasures(pivotId, measures) {
|
|
67781
67809
|
for (const measure of measures) {
|
|
67782
67810
|
if (measure.computedBy) {
|
|
67783
|
-
const sheetId = measure.computedBy.sheetId;
|
|
67784
67811
|
const compiledFormula = this.compileMeasureFormula(measure.computedBy.sheetId, measure.computedBy.formula);
|
|
67785
|
-
this.history.update("compiledMeasureFormulas",
|
|
67812
|
+
this.history.update("compiledMeasureFormulas", pivotId, measure.id, "formula", compiledFormula);
|
|
67786
67813
|
}
|
|
67787
67814
|
}
|
|
67815
|
+
for (const measure of measures) {
|
|
67816
|
+
if (measure.computedBy) {
|
|
67817
|
+
const dependencies = this.computeMeasureFullDependencies(pivotId, measure);
|
|
67818
|
+
this.history.update("compiledMeasureFormulas", pivotId, measure.id, "dependencies", dependencies);
|
|
67819
|
+
}
|
|
67820
|
+
}
|
|
67821
|
+
}
|
|
67822
|
+
computeMeasureFullDependencies(pivotId, measure, exploredMeasures = new Set()) {
|
|
67823
|
+
const rangeDependencies = [];
|
|
67824
|
+
const definition = this.getPivotCoreDefinition(pivotId);
|
|
67825
|
+
const formula = this.getMeasureCompiledFormula(pivotId, measure);
|
|
67826
|
+
exploredMeasures.add(measure.id);
|
|
67827
|
+
for (const token of formula.tokens) {
|
|
67828
|
+
if (token.type !== "SYMBOL") {
|
|
67829
|
+
continue;
|
|
67830
|
+
}
|
|
67831
|
+
const otherMeasure = definition.measures.find((measureCandidate) => getCanonicalSymbolName(measureCandidate.id) === token.value &&
|
|
67832
|
+
measure.id !== measureCandidate.id);
|
|
67833
|
+
if (!otherMeasure || exploredMeasures.has(otherMeasure.id) || !otherMeasure.computedBy) {
|
|
67834
|
+
continue;
|
|
67835
|
+
}
|
|
67836
|
+
rangeDependencies.push(...this.computeMeasureFullDependencies(pivotId, otherMeasure, exploredMeasures));
|
|
67837
|
+
}
|
|
67838
|
+
rangeDependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
|
|
67839
|
+
return rangeDependencies;
|
|
67788
67840
|
}
|
|
67789
67841
|
insertPivot(position, formulaId, table) {
|
|
67790
67842
|
this.resizeSheet(position.sheetId, position, table);
|
|
@@ -67844,21 +67896,17 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
67844
67896
|
dependencies: rangeDependencies,
|
|
67845
67897
|
};
|
|
67846
67898
|
}
|
|
67847
|
-
replaceMeasureFormula(
|
|
67848
|
-
|
|
67849
|
-
|
|
67850
|
-
|
|
67851
|
-
const pivot = this.pivots[pivotId];
|
|
67852
|
-
if (!pivot) {
|
|
67853
|
-
continue;
|
|
67854
|
-
}
|
|
67855
|
-
for (const measure of pivot.definition.measures) {
|
|
67856
|
-
if (measure.computedBy?.formula === formulaString) {
|
|
67857
|
-
const measureIndex = pivot.definition.measures.indexOf(measure);
|
|
67858
|
-
this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", { formula: newFormulaString, sheetId });
|
|
67859
|
-
}
|
|
67860
|
-
}
|
|
67899
|
+
replaceMeasureFormula(pivotId, measure, newFormulaString) {
|
|
67900
|
+
const pivot = this.pivots[pivotId];
|
|
67901
|
+
if (!pivot) {
|
|
67902
|
+
return;
|
|
67861
67903
|
}
|
|
67904
|
+
const measureIndex = pivot.definition.measures.indexOf(measure);
|
|
67905
|
+
this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", {
|
|
67906
|
+
formula: newFormulaString,
|
|
67907
|
+
sheetId: measure.computedBy.sheetId,
|
|
67908
|
+
});
|
|
67909
|
+
this.compileCalculatedMeasures(pivotId, pivot.definition.measures);
|
|
67862
67910
|
}
|
|
67863
67911
|
checkSortedColumnInMeasures(definition) {
|
|
67864
67912
|
const measures = definition.measures.map((measure) => measure.id);
|
|
@@ -71708,14 +71756,16 @@ const PERCENT_FORMAT = "0.00%";
|
|
|
71708
71756
|
function withPivotPresentationLayer (PivotClass) {
|
|
71709
71757
|
class PivotPresentationLayer extends PivotClass {
|
|
71710
71758
|
getters;
|
|
71759
|
+
pivotId;
|
|
71711
71760
|
cache = {};
|
|
71712
71761
|
rankAsc = {};
|
|
71713
71762
|
rankDesc = {};
|
|
71714
71763
|
runningTotal = {};
|
|
71715
71764
|
runningTotalInPercent = {};
|
|
71716
|
-
constructor(custom, params) {
|
|
71765
|
+
constructor(pivotId, custom, params) {
|
|
71717
71766
|
super(custom, params);
|
|
71718
71767
|
this.getters = params.getters;
|
|
71768
|
+
this.pivotId = pivotId;
|
|
71719
71769
|
}
|
|
71720
71770
|
markAsDirtyForEvaluation() {
|
|
71721
71771
|
this.cache = {};
|
|
@@ -71765,7 +71815,7 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
71765
71815
|
return handleError(error, measure.aggregator.toUpperCase());
|
|
71766
71816
|
}
|
|
71767
71817
|
}
|
|
71768
|
-
const formula = this.getters.getMeasureCompiledFormula(measure);
|
|
71818
|
+
const formula = this.getters.getMeasureCompiledFormula(this.pivotId, measure);
|
|
71769
71819
|
const getSymbolValue = (symbolName) => {
|
|
71770
71820
|
const { columns, rows } = this.definition;
|
|
71771
71821
|
if (columns.find((col) => col.nameWithGranularity === symbolName)) {
|
|
@@ -72520,7 +72570,7 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
72520
72570
|
const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
|
|
72521
72571
|
if (!(pivotId in this.pivots)) {
|
|
72522
72572
|
const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
|
|
72523
|
-
this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
|
|
72573
|
+
this.pivots[pivotId] = new Pivot(pivotId, this.custom, { definition, getters: this.getters });
|
|
72524
72574
|
}
|
|
72525
72575
|
else if (recreate) {
|
|
72526
72576
|
this.pivots[pivotId].onDefinitionChange(definition);
|
|
@@ -89125,6 +89175,6 @@ exports.tokenColors = tokenColors;
|
|
|
89125
89175
|
exports.tokenize = tokenize;
|
|
89126
89176
|
|
|
89127
89177
|
|
|
89128
|
-
__info__.version = "19.0.
|
|
89129
|
-
__info__.date = "2026-01-
|
|
89130
|
-
__info__.hash = "
|
|
89178
|
+
__info__.version = "19.0.17";
|
|
89179
|
+
__info__.date = "2026-01-14T10:01:24.044Z";
|
|
89180
|
+
__info__.hash = "2165bad";
|
package/dist/o-spreadsheet.d.ts
CHANGED
|
@@ -2290,14 +2290,18 @@ interface Pivot$1 {
|
|
|
2290
2290
|
definition: PivotCoreDefinition;
|
|
2291
2291
|
formulaId: string;
|
|
2292
2292
|
}
|
|
2293
|
+
interface MeasureState {
|
|
2294
|
+
formula: RangeCompiledFormula;
|
|
2295
|
+
dependencies: Range[];
|
|
2296
|
+
}
|
|
2293
2297
|
interface CoreState {
|
|
2294
2298
|
nextFormulaId: number;
|
|
2295
2299
|
pivots: Record<UID, Pivot$1 | undefined>;
|
|
2296
2300
|
formulaIds: Record<UID, string | undefined>;
|
|
2297
|
-
compiledMeasureFormulas: Record<UID, Record<string,
|
|
2301
|
+
compiledMeasureFormulas: Record<UID, Record<string, MeasureState | undefined>>;
|
|
2298
2302
|
}
|
|
2299
2303
|
declare class PivotCorePlugin extends CorePlugin<CoreState> implements CoreState {
|
|
2300
|
-
static getters: readonly ["getPivotCoreDefinition", "getPivotDisplayName", "getPivotId", "getPivotFormulaId", "getPivotIds", "getMeasureCompiledFormula", "getPivotName", "isExistingPivot"];
|
|
2304
|
+
static getters: readonly ["getPivotCoreDefinition", "getPivotDisplayName", "getPivotId", "getPivotFormulaId", "getPivotIds", "getMeasureCompiledFormula", "getPivotName", "isExistingPivot", "getMeasureFullDependencies"];
|
|
2301
2305
|
readonly nextFormulaId: number;
|
|
2302
2306
|
readonly pivots: {
|
|
2303
2307
|
[pivotId: UID]: Pivot$1 | undefined;
|
|
@@ -2305,7 +2309,7 @@ declare class PivotCorePlugin extends CorePlugin<CoreState> implements CoreState
|
|
|
2305
2309
|
readonly formulaIds: {
|
|
2306
2310
|
[formulaId: UID]: UID | undefined;
|
|
2307
2311
|
};
|
|
2308
|
-
readonly compiledMeasureFormulas: Record<UID, Record<string,
|
|
2312
|
+
readonly compiledMeasureFormulas: Record<UID, Record<string, MeasureState>>;
|
|
2309
2313
|
allowDispatch(cmd: CoreCommand): CommandResult | CommandResult[];
|
|
2310
2314
|
handle(cmd: CoreCommand): void;
|
|
2311
2315
|
adaptRanges(applyChange: ApplyRangeChange): void;
|
|
@@ -2324,9 +2328,11 @@ declare class PivotCorePlugin extends CorePlugin<CoreState> implements CoreState
|
|
|
2324
2328
|
getPivotFormulaId(pivotId: UID): string;
|
|
2325
2329
|
getPivotIds(): UID[];
|
|
2326
2330
|
isExistingPivot(pivotId: UID): boolean;
|
|
2327
|
-
getMeasureCompiledFormula(measure: PivotCoreMeasure): RangeCompiledFormula;
|
|
2331
|
+
getMeasureCompiledFormula(pivotId: UID, measure: PivotCoreMeasure): RangeCompiledFormula;
|
|
2332
|
+
getMeasureFullDependencies(pivotId: UID, measure: PivotCoreMeasure): Range[];
|
|
2328
2333
|
private addPivot;
|
|
2329
2334
|
private compileCalculatedMeasures;
|
|
2335
|
+
private computeMeasureFullDependencies;
|
|
2330
2336
|
private insertPivot;
|
|
2331
2337
|
private resizeSheet;
|
|
2332
2338
|
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 19.0.
|
|
6
|
-
* @date 2026-01-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.0.17
|
|
6
|
+
* @date 2026-01-14T10:01:24.044Z
|
|
7
|
+
* @hash 2165bad
|
|
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';
|
|
@@ -20098,9 +20098,10 @@ function assertDomainLength(domain) {
|
|
|
20098
20098
|
throw new EvaluationError(_t("Function PIVOT takes an even number of arguments."));
|
|
20099
20099
|
}
|
|
20100
20100
|
}
|
|
20101
|
-
function addPivotDependencies(evalContext,
|
|
20101
|
+
function addPivotDependencies(evalContext, pivotId, forMeasures) {
|
|
20102
20102
|
//TODO This function can be very costly when used with PIVOT.VALUE and PIVOT.HEADER
|
|
20103
20103
|
const dependencies = [];
|
|
20104
|
+
const coreDefinition = evalContext.getters.getPivotCoreDefinition(pivotId);
|
|
20104
20105
|
if (coreDefinition.type === "SPREADSHEET" && coreDefinition.dataSet) {
|
|
20105
20106
|
const { sheetId, zone } = coreDefinition.dataSet;
|
|
20106
20107
|
const xc = zoneToXc(zone);
|
|
@@ -20117,8 +20118,7 @@ function addPivotDependencies(evalContext, coreDefinition, forMeasures) {
|
|
|
20117
20118
|
}
|
|
20118
20119
|
for (const measure of forMeasures) {
|
|
20119
20120
|
if (measure.computedBy) {
|
|
20120
|
-
|
|
20121
|
-
dependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
|
|
20121
|
+
dependencies.push(...evalContext.getters.getMeasureFullDependencies(pivotId, measure));
|
|
20122
20122
|
}
|
|
20123
20123
|
}
|
|
20124
20124
|
const originPosition = evalContext.__originCellPosition;
|
|
@@ -20615,7 +20615,7 @@ const PIVOT_VALUE = {
|
|
|
20615
20615
|
assertDomainLength(domainArgs);
|
|
20616
20616
|
const pivot = this.getters.getPivot(pivotId);
|
|
20617
20617
|
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
20618
|
-
addPivotDependencies(this,
|
|
20618
|
+
addPivotDependencies(this, pivotId, coreDefinition.measures.filter((m) => m.id === _measure));
|
|
20619
20619
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
20620
20620
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
20621
20621
|
if (error) {
|
|
@@ -20648,8 +20648,7 @@ const PIVOT_HEADER = {
|
|
|
20648
20648
|
const _pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
20649
20649
|
assertDomainLength(domainArgs);
|
|
20650
20650
|
const pivot = this.getters.getPivot(_pivotId);
|
|
20651
|
-
|
|
20652
|
-
addPivotDependencies(this, coreDefinition, []);
|
|
20651
|
+
addPivotDependencies(this, _pivotId, []);
|
|
20653
20652
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
20654
20653
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
20655
20654
|
if (error) {
|
|
@@ -20707,7 +20706,7 @@ const PIVOT = {
|
|
|
20707
20706
|
const pivotId = getPivotId(_pivotFormulaId, this.getters);
|
|
20708
20707
|
const pivot = this.getters.getPivot(pivotId);
|
|
20709
20708
|
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
20710
|
-
addPivotDependencies(this,
|
|
20709
|
+
addPivotDependencies(this, pivotId, coreDefinition.measures);
|
|
20711
20710
|
pivot.init({ reload: pivot.needsReevaluation });
|
|
20712
20711
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
20713
20712
|
if (error) {
|
|
@@ -35482,7 +35481,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
35482
35481
|
}
|
|
35483
35482
|
captureSelection(zone, col, row) {
|
|
35484
35483
|
this.model.selection.capture(this, {
|
|
35485
|
-
cell: { col: col ?? zone.left, row: row ?? zone.
|
|
35484
|
+
cell: { col: col ?? zone.left, row: row ?? zone.top },
|
|
35486
35485
|
zone,
|
|
35487
35486
|
}, {
|
|
35488
35487
|
handleEvent: this.handleEvent.bind(this),
|
|
@@ -57875,6 +57874,12 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
57875
57874
|
case "ACTIVATE_SHEET":
|
|
57876
57875
|
this.isSearchDirty = true;
|
|
57877
57876
|
this.shouldFinalizeUpdateSelection = true;
|
|
57877
|
+
if (this.searchOptions.specificRange) {
|
|
57878
|
+
this.searchOptions.specificRange = {
|
|
57879
|
+
...this.searchOptions.specificRange,
|
|
57880
|
+
sheetId: this.getters.getActiveSheetId(),
|
|
57881
|
+
};
|
|
57882
|
+
}
|
|
57878
57883
|
break;
|
|
57879
57884
|
case "REPLACE_SEARCH":
|
|
57880
57885
|
for (const match of cmd.matches) {
|
|
@@ -58294,9 +58299,20 @@ class FindAndReplacePanel extends Component {
|
|
|
58294
58299
|
const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.dataRange);
|
|
58295
58300
|
this.store.updateSearchOptions({ specificRange });
|
|
58296
58301
|
}
|
|
58302
|
+
get specificRange() {
|
|
58303
|
+
const range = this.store.searchOptions.specificRange;
|
|
58304
|
+
return range ? this.env.model.getters.getRangeString(range, "forceSheetReference") : "";
|
|
58305
|
+
}
|
|
58297
58306
|
get pendingSearch() {
|
|
58298
58307
|
return this.updateSearchContent.isDebouncePending();
|
|
58299
58308
|
}
|
|
58309
|
+
get selectionInputKey() {
|
|
58310
|
+
// Selections input are made to work with objects linked to a sheet id. They store the active sheet id at their creation,
|
|
58311
|
+
// and have specific behaviour linked to it (eg. go back to the initial sheet after confirmation).
|
|
58312
|
+
// We don't want all those behaviors here, so we force the recreation of the component when the active sheet changes.
|
|
58313
|
+
// The only drawback is that the input loses focus when changing sheet.
|
|
58314
|
+
return this.env.model.getters.getActiveSheetId();
|
|
58315
|
+
}
|
|
58300
58316
|
}
|
|
58301
58317
|
|
|
58302
58318
|
css /* scss */ `
|
|
@@ -67606,6 +67622,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
67606
67622
|
"getMeasureCompiledFormula",
|
|
67607
67623
|
"getPivotName",
|
|
67608
67624
|
"isExistingPivot",
|
|
67625
|
+
"getMeasureFullDependencies",
|
|
67609
67626
|
];
|
|
67610
67627
|
nextFormulaId = 1;
|
|
67611
67628
|
pivots = {};
|
|
@@ -67688,7 +67705,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
67688
67705
|
}
|
|
67689
67706
|
case "UPDATE_PIVOT": {
|
|
67690
67707
|
this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
|
|
67691
|
-
this.compileCalculatedMeasures(cmd.pivot.measures);
|
|
67708
|
+
this.compileCalculatedMeasures(cmd.pivotId, cmd.pivot.measures);
|
|
67692
67709
|
break;
|
|
67693
67710
|
}
|
|
67694
67711
|
}
|
|
@@ -67706,9 +67723,14 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
67706
67723
|
this.history.update("pivots", pivotId, "definition", newDefinition);
|
|
67707
67724
|
}
|
|
67708
67725
|
}
|
|
67709
|
-
for (const
|
|
67710
|
-
for (const
|
|
67711
|
-
const
|
|
67726
|
+
for (const pivotId in this.compiledMeasureFormulas) {
|
|
67727
|
+
for (const measureId in this.compiledMeasureFormulas[pivotId]) {
|
|
67728
|
+
const measure = this.pivots[pivotId]?.definition.measures.find((m) => m.id === measureId);
|
|
67729
|
+
if (!measure || !measure.computedBy) {
|
|
67730
|
+
continue;
|
|
67731
|
+
}
|
|
67732
|
+
const sheetId = measure.computedBy.sheetId;
|
|
67733
|
+
const compiledFormula = this.compiledMeasureFormulas[pivotId][measureId].formula;
|
|
67712
67734
|
const newDependencies = [];
|
|
67713
67735
|
for (const range of compiledFormula.dependencies) {
|
|
67714
67736
|
const change = applyChange(range);
|
|
@@ -67720,8 +67742,9 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
67720
67742
|
}
|
|
67721
67743
|
}
|
|
67722
67744
|
const newFormulaString = this.getters.getFormulaString(sheetId, compiledFormula.tokens, newDependencies);
|
|
67723
|
-
|
|
67724
|
-
|
|
67745
|
+
const oldFormulaString = measure.computedBy.formula;
|
|
67746
|
+
if (newFormulaString !== oldFormulaString) {
|
|
67747
|
+
this.replaceMeasureFormula(pivotId, measure, newFormulaString);
|
|
67725
67748
|
}
|
|
67726
67749
|
}
|
|
67727
67750
|
}
|
|
@@ -67759,30 +67782,59 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
67759
67782
|
isExistingPivot(pivotId) {
|
|
67760
67783
|
return pivotId in this.pivots;
|
|
67761
67784
|
}
|
|
67762
|
-
getMeasureCompiledFormula(measure) {
|
|
67785
|
+
getMeasureCompiledFormula(pivotId, measure) {
|
|
67763
67786
|
if (!measure.computedBy) {
|
|
67764
67787
|
throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
|
|
67765
67788
|
}
|
|
67766
|
-
|
|
67767
|
-
|
|
67789
|
+
return this.compiledMeasureFormulas[pivotId][measure.id].formula;
|
|
67790
|
+
}
|
|
67791
|
+
getMeasureFullDependencies(pivotId, measure) {
|
|
67792
|
+
if (!measure.computedBy) {
|
|
67793
|
+
throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
|
|
67794
|
+
}
|
|
67795
|
+
return this.compiledMeasureFormulas[pivotId][measure.id].dependencies;
|
|
67768
67796
|
}
|
|
67769
67797
|
// -------------------------------------------------------------------------
|
|
67770
67798
|
// Private
|
|
67771
67799
|
// -------------------------------------------------------------------------
|
|
67772
67800
|
addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
|
|
67773
67801
|
this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
|
|
67774
|
-
this.compileCalculatedMeasures(pivot.measures);
|
|
67802
|
+
this.compileCalculatedMeasures(pivotId, pivot.measures);
|
|
67775
67803
|
this.history.update("formulaIds", formulaId, pivotId);
|
|
67776
67804
|
this.history.update("nextFormulaId", this.nextFormulaId + 1);
|
|
67777
67805
|
}
|
|
67778
|
-
compileCalculatedMeasures(measures) {
|
|
67806
|
+
compileCalculatedMeasures(pivotId, measures) {
|
|
67779
67807
|
for (const measure of measures) {
|
|
67780
67808
|
if (measure.computedBy) {
|
|
67781
|
-
const sheetId = measure.computedBy.sheetId;
|
|
67782
67809
|
const compiledFormula = this.compileMeasureFormula(measure.computedBy.sheetId, measure.computedBy.formula);
|
|
67783
|
-
this.history.update("compiledMeasureFormulas",
|
|
67810
|
+
this.history.update("compiledMeasureFormulas", pivotId, measure.id, "formula", compiledFormula);
|
|
67784
67811
|
}
|
|
67785
67812
|
}
|
|
67813
|
+
for (const measure of measures) {
|
|
67814
|
+
if (measure.computedBy) {
|
|
67815
|
+
const dependencies = this.computeMeasureFullDependencies(pivotId, measure);
|
|
67816
|
+
this.history.update("compiledMeasureFormulas", pivotId, measure.id, "dependencies", dependencies);
|
|
67817
|
+
}
|
|
67818
|
+
}
|
|
67819
|
+
}
|
|
67820
|
+
computeMeasureFullDependencies(pivotId, measure, exploredMeasures = new Set()) {
|
|
67821
|
+
const rangeDependencies = [];
|
|
67822
|
+
const definition = this.getPivotCoreDefinition(pivotId);
|
|
67823
|
+
const formula = this.getMeasureCompiledFormula(pivotId, measure);
|
|
67824
|
+
exploredMeasures.add(measure.id);
|
|
67825
|
+
for (const token of formula.tokens) {
|
|
67826
|
+
if (token.type !== "SYMBOL") {
|
|
67827
|
+
continue;
|
|
67828
|
+
}
|
|
67829
|
+
const otherMeasure = definition.measures.find((measureCandidate) => getCanonicalSymbolName(measureCandidate.id) === token.value &&
|
|
67830
|
+
measure.id !== measureCandidate.id);
|
|
67831
|
+
if (!otherMeasure || exploredMeasures.has(otherMeasure.id) || !otherMeasure.computedBy) {
|
|
67832
|
+
continue;
|
|
67833
|
+
}
|
|
67834
|
+
rangeDependencies.push(...this.computeMeasureFullDependencies(pivotId, otherMeasure, exploredMeasures));
|
|
67835
|
+
}
|
|
67836
|
+
rangeDependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
|
|
67837
|
+
return rangeDependencies;
|
|
67786
67838
|
}
|
|
67787
67839
|
insertPivot(position, formulaId, table) {
|
|
67788
67840
|
this.resizeSheet(position.sheetId, position, table);
|
|
@@ -67842,21 +67894,17 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
67842
67894
|
dependencies: rangeDependencies,
|
|
67843
67895
|
};
|
|
67844
67896
|
}
|
|
67845
|
-
replaceMeasureFormula(
|
|
67846
|
-
|
|
67847
|
-
|
|
67848
|
-
|
|
67849
|
-
const pivot = this.pivots[pivotId];
|
|
67850
|
-
if (!pivot) {
|
|
67851
|
-
continue;
|
|
67852
|
-
}
|
|
67853
|
-
for (const measure of pivot.definition.measures) {
|
|
67854
|
-
if (measure.computedBy?.formula === formulaString) {
|
|
67855
|
-
const measureIndex = pivot.definition.measures.indexOf(measure);
|
|
67856
|
-
this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", { formula: newFormulaString, sheetId });
|
|
67857
|
-
}
|
|
67858
|
-
}
|
|
67897
|
+
replaceMeasureFormula(pivotId, measure, newFormulaString) {
|
|
67898
|
+
const pivot = this.pivots[pivotId];
|
|
67899
|
+
if (!pivot) {
|
|
67900
|
+
return;
|
|
67859
67901
|
}
|
|
67902
|
+
const measureIndex = pivot.definition.measures.indexOf(measure);
|
|
67903
|
+
this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", {
|
|
67904
|
+
formula: newFormulaString,
|
|
67905
|
+
sheetId: measure.computedBy.sheetId,
|
|
67906
|
+
});
|
|
67907
|
+
this.compileCalculatedMeasures(pivotId, pivot.definition.measures);
|
|
67860
67908
|
}
|
|
67861
67909
|
checkSortedColumnInMeasures(definition) {
|
|
67862
67910
|
const measures = definition.measures.map((measure) => measure.id);
|
|
@@ -71706,14 +71754,16 @@ const PERCENT_FORMAT = "0.00%";
|
|
|
71706
71754
|
function withPivotPresentationLayer (PivotClass) {
|
|
71707
71755
|
class PivotPresentationLayer extends PivotClass {
|
|
71708
71756
|
getters;
|
|
71757
|
+
pivotId;
|
|
71709
71758
|
cache = {};
|
|
71710
71759
|
rankAsc = {};
|
|
71711
71760
|
rankDesc = {};
|
|
71712
71761
|
runningTotal = {};
|
|
71713
71762
|
runningTotalInPercent = {};
|
|
71714
|
-
constructor(custom, params) {
|
|
71763
|
+
constructor(pivotId, custom, params) {
|
|
71715
71764
|
super(custom, params);
|
|
71716
71765
|
this.getters = params.getters;
|
|
71766
|
+
this.pivotId = pivotId;
|
|
71717
71767
|
}
|
|
71718
71768
|
markAsDirtyForEvaluation() {
|
|
71719
71769
|
this.cache = {};
|
|
@@ -71763,7 +71813,7 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
71763
71813
|
return handleError(error, measure.aggregator.toUpperCase());
|
|
71764
71814
|
}
|
|
71765
71815
|
}
|
|
71766
|
-
const formula = this.getters.getMeasureCompiledFormula(measure);
|
|
71816
|
+
const formula = this.getters.getMeasureCompiledFormula(this.pivotId, measure);
|
|
71767
71817
|
const getSymbolValue = (symbolName) => {
|
|
71768
71818
|
const { columns, rows } = this.definition;
|
|
71769
71819
|
if (columns.find((col) => col.nameWithGranularity === symbolName)) {
|
|
@@ -72518,7 +72568,7 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
72518
72568
|
const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
|
|
72519
72569
|
if (!(pivotId in this.pivots)) {
|
|
72520
72570
|
const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
|
|
72521
|
-
this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
|
|
72571
|
+
this.pivots[pivotId] = new Pivot(pivotId, this.custom, { definition, getters: this.getters });
|
|
72522
72572
|
}
|
|
72523
72573
|
else if (recreate) {
|
|
72524
72574
|
this.pivots[pivotId].onDefinitionChange(definition);
|
|
@@ -89073,6 +89123,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
|
|
|
89073
89123
|
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, getCaretDownSvg, getCaretUpSvg, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
89074
89124
|
|
|
89075
89125
|
|
|
89076
|
-
__info__.version = "19.0.
|
|
89077
|
-
__info__.date = "2026-01-
|
|
89078
|
-
__info__.hash = "
|
|
89126
|
+
__info__.version = "19.0.17";
|
|
89127
|
+
__info__.date = "2026-01-14T10:01:24.044Z";
|
|
89128
|
+
__info__.hash = "2165bad";
|