@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.
@@ -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.16
6
- * @date 2026-01-07T16:21:15.857Z
7
- * @hash 9f3f13a
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, coreDefinition, forMeasures) {
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
- const formula = evalContext.getters.getMeasureCompiledFormula(measure);
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, coreDefinition, coreDefinition.measures.filter((m) => m.id === _measure));
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
- const coreDefinition = this.getters.getPivotCoreDefinition(_pivotId);
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, coreDefinition, coreDefinition.measures);
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.right },
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 sheetId in this.compiledMeasureFormulas) {
67712
- for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
67713
- const compiledFormula = this.compiledMeasureFormulas[sheetId][formulaString];
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
- if (newFormulaString !== formulaString) {
67726
- this.replaceMeasureFormula(sheetId, formulaString, newFormulaString);
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
- const sheetId = measure.computedBy.sheetId;
67769
- return this.compiledMeasureFormulas[sheetId][measure.computedBy.formula];
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", sheetId, measure.computedBy.formula, compiledFormula);
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(sheetId, formulaString, newFormulaString) {
67848
- this.history.update("compiledMeasureFormulas", sheetId, formulaString, undefined);
67849
- this.history.update("compiledMeasureFormulas", sheetId, newFormulaString, this.compileMeasureFormula(sheetId, newFormulaString));
67850
- for (const pivotId in this.pivots) {
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.16";
89129
- __info__.date = "2026-01-07T16:21:15.857Z";
89130
- __info__.hash = "9f3f13a";
89178
+ __info__.version = "19.0.17";
89179
+ __info__.date = "2026-01-14T10:01:24.044Z";
89180
+ __info__.hash = "2165bad";
@@ -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, RangeCompiledFormula | undefined>>;
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, RangeCompiledFormula>>;
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.16
6
- * @date 2026-01-07T16:21:15.857Z
7
- * @hash 9f3f13a
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, coreDefinition, forMeasures) {
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
- const formula = evalContext.getters.getMeasureCompiledFormula(measure);
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, coreDefinition, coreDefinition.measures.filter((m) => m.id === _measure));
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
- const coreDefinition = this.getters.getPivotCoreDefinition(_pivotId);
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, coreDefinition, coreDefinition.measures);
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.right },
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 sheetId in this.compiledMeasureFormulas) {
67710
- for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
67711
- const compiledFormula = this.compiledMeasureFormulas[sheetId][formulaString];
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
- if (newFormulaString !== formulaString) {
67724
- this.replaceMeasureFormula(sheetId, formulaString, newFormulaString);
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
- const sheetId = measure.computedBy.sheetId;
67767
- return this.compiledMeasureFormulas[sheetId][measure.computedBy.formula];
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", sheetId, measure.computedBy.formula, compiledFormula);
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(sheetId, formulaString, newFormulaString) {
67846
- this.history.update("compiledMeasureFormulas", sheetId, formulaString, undefined);
67847
- this.history.update("compiledMeasureFormulas", sheetId, newFormulaString, this.compileMeasureFormula(sheetId, newFormulaString));
67848
- for (const pivotId in this.pivots) {
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.16";
89077
- __info__.date = "2026-01-07T16:21:15.857Z";
89078
- __info__.hash = "9f3f13a";
89126
+ __info__.version = "19.0.17";
89127
+ __info__.date = "2026-01-14T10:01:24.044Z";
89128
+ __info__.hash = "2165bad";