@odoo/o-spreadsheet 18.0.53 → 18.0.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 18.0.53
6
- * @date 2025-12-26T10:18:09.933Z
7
- * @hash 7ca8390
5
+ * @version 18.0.54
6
+ * @date 2026-01-14T10:00:02.287Z
7
+ * @hash c0048a0
8
8
  */
9
9
 
10
10
  'use strict';
@@ -18565,9 +18565,10 @@ function assertDomainLength(domain) {
18565
18565
  throw new EvaluationError(_t("Function PIVOT takes an even number of arguments."));
18566
18566
  }
18567
18567
  }
18568
- function addPivotDependencies(evalContext, coreDefinition, forMeasures) {
18568
+ function addPivotDependencies(evalContext, pivotId, forMeasures) {
18569
18569
  //TODO This function can be very costly when used with PIVOT.VALUE and PIVOT.HEADER
18570
18570
  const dependencies = [];
18571
+ const coreDefinition = evalContext.getters.getPivotCoreDefinition(pivotId);
18571
18572
  if (coreDefinition.type === "SPREADSHEET" && coreDefinition.dataSet) {
18572
18573
  const { sheetId, zone } = coreDefinition.dataSet;
18573
18574
  const xc = zoneToXc(zone);
@@ -18584,8 +18585,7 @@ function addPivotDependencies(evalContext, coreDefinition, forMeasures) {
18584
18585
  }
18585
18586
  for (const measure of forMeasures) {
18586
18587
  if (measure.computedBy) {
18587
- const formula = evalContext.getters.getMeasureCompiledFormula(measure);
18588
- dependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
18588
+ dependencies.push(...evalContext.getters.getMeasureFullDependencies(pivotId, measure));
18589
18589
  }
18590
18590
  }
18591
18591
  const originPosition = evalContext.__originCellPosition;
@@ -19026,7 +19026,7 @@ const PIVOT_VALUE = {
19026
19026
  assertDomainLength(domainArgs);
19027
19027
  const pivot = this.getters.getPivot(pivotId);
19028
19028
  const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
19029
- addPivotDependencies(this, coreDefinition, coreDefinition.measures.filter((m) => m.id === _measure));
19029
+ addPivotDependencies(this, pivotId, coreDefinition.measures.filter((m) => m.id === _measure));
19030
19030
  pivot.init({ reload: pivot.needsReevaluation });
19031
19031
  const error = pivot.assertIsValid({ throwOnError: false });
19032
19032
  if (error) {
@@ -19059,8 +19059,7 @@ const PIVOT_HEADER = {
19059
19059
  const _pivotId = getPivotId(_pivotFormulaId, this.getters);
19060
19060
  assertDomainLength(domainArgs);
19061
19061
  const pivot = this.getters.getPivot(_pivotId);
19062
- const coreDefinition = this.getters.getPivotCoreDefinition(_pivotId);
19063
- addPivotDependencies(this, coreDefinition, []);
19062
+ addPivotDependencies(this, _pivotId, []);
19064
19063
  pivot.init({ reload: pivot.needsReevaluation });
19065
19064
  const error = pivot.assertIsValid({ throwOnError: false });
19066
19065
  if (error) {
@@ -19114,7 +19113,7 @@ const PIVOT = {
19114
19113
  const pivotId = getPivotId(_pivotFormulaId, this.getters);
19115
19114
  const pivot = this.getters.getPivot(pivotId);
19116
19115
  const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
19117
- addPivotDependencies(this, coreDefinition, coreDefinition.measures);
19116
+ addPivotDependencies(this, pivotId, coreDefinition.measures);
19118
19117
  pivot.init({ reload: pivot.needsReevaluation });
19119
19118
  const error = pivot.assertIsValid({ throwOnError: false });
19120
19119
  if (error) {
@@ -42461,6 +42460,11 @@ class FindAndReplaceStore extends SpreadsheetStore {
42461
42460
  case "UPDATE_CELL":
42462
42461
  case "ACTIVATE_SHEET":
42463
42462
  this.isSearchDirty = true;
42463
+ if (this.searchOptions.specificRange) {
42464
+ this.searchOptions.specificRange = this.searchOptions.specificRange.clone({
42465
+ sheetId: this.getters.getActiveSheetId(),
42466
+ });
42467
+ }
42464
42468
  break;
42465
42469
  case "REPLACE_SEARCH":
42466
42470
  for (const match of cmd.matches) {
@@ -42866,9 +42870,20 @@ class FindAndReplacePanel extends owl.Component {
42866
42870
  const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.dataRange);
42867
42871
  this.store.updateSearchOptions({ specificRange });
42868
42872
  }
42873
+ get specificRange() {
42874
+ const range = this.store.searchOptions.specificRange;
42875
+ return range ? this.env.model.getters.getRangeString(range, "forceSheetReference") : "";
42876
+ }
42869
42877
  get pendingSearch() {
42870
42878
  return this.updateSearchContent.isDebouncePending();
42871
42879
  }
42880
+ get selectionInputKey() {
42881
+ // Selections input are made to work with objects linked to a sheet id. They store the active sheet id at their creation,
42882
+ // and have specific behaviour linked to it (eg. go back to the initial sheet after confirmation).
42883
+ // We don't want all those behaviors here, so we force the recreation of the component when the active sheet changes.
42884
+ // The only drawback is that the input loses focus when changing sheet.
42885
+ return this.env.model.getters.getActiveSheetId();
42886
+ }
42872
42887
  }
42873
42888
 
42874
42889
  css /* scss */ `
@@ -57205,6 +57220,7 @@ class PivotCorePlugin extends CorePlugin {
57205
57220
  "getMeasureCompiledFormula",
57206
57221
  "getPivotName",
57207
57222
  "isExistingPivot",
57223
+ "getMeasureFullDependencies",
57208
57224
  ];
57209
57225
  nextFormulaId = 1;
57210
57226
  pivots = {};
@@ -57287,7 +57303,7 @@ class PivotCorePlugin extends CorePlugin {
57287
57303
  }
57288
57304
  case "UPDATE_PIVOT": {
57289
57305
  this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
57290
- this.compileCalculatedMeasures(cmd.pivot.measures);
57306
+ this.compileCalculatedMeasures(cmd.pivotId, cmd.pivot.measures);
57291
57307
  break;
57292
57308
  }
57293
57309
  }
@@ -57305,9 +57321,14 @@ class PivotCorePlugin extends CorePlugin {
57305
57321
  this.history.update("pivots", pivotId, "definition", newDefinition);
57306
57322
  }
57307
57323
  }
57308
- for (const sheetId in this.compiledMeasureFormulas) {
57309
- for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
57310
- const compiledFormula = this.compiledMeasureFormulas[sheetId][formulaString];
57324
+ for (const pivotId in this.compiledMeasureFormulas) {
57325
+ for (const measureId in this.compiledMeasureFormulas[pivotId]) {
57326
+ const measure = this.pivots[pivotId]?.definition.measures.find((m) => m.id === measureId);
57327
+ if (!measure || !measure.computedBy) {
57328
+ continue;
57329
+ }
57330
+ const sheetId = measure.computedBy.sheetId;
57331
+ const compiledFormula = this.compiledMeasureFormulas[pivotId][measureId].formula;
57311
57332
  const newDependencies = [];
57312
57333
  for (const range of compiledFormula.dependencies) {
57313
57334
  const change = applyChange(range);
@@ -57319,8 +57340,9 @@ class PivotCorePlugin extends CorePlugin {
57319
57340
  }
57320
57341
  }
57321
57342
  const newFormulaString = this.getters.getFormulaString(sheetId, compiledFormula.tokens, newDependencies);
57322
- if (newFormulaString !== formulaString) {
57323
- this.replaceMeasureFormula(sheetId, formulaString, newFormulaString);
57343
+ const oldFormulaString = measure.computedBy.formula;
57344
+ if (newFormulaString !== oldFormulaString) {
57345
+ this.replaceMeasureFormula(pivotId, measure, newFormulaString);
57324
57346
  }
57325
57347
  }
57326
57348
  }
@@ -57358,30 +57380,59 @@ class PivotCorePlugin extends CorePlugin {
57358
57380
  isExistingPivot(pivotId) {
57359
57381
  return pivotId in this.pivots;
57360
57382
  }
57361
- getMeasureCompiledFormula(measure) {
57383
+ getMeasureCompiledFormula(pivotId, measure) {
57362
57384
  if (!measure.computedBy) {
57363
57385
  throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
57364
57386
  }
57365
- const sheetId = measure.computedBy.sheetId;
57366
- return this.compiledMeasureFormulas[sheetId][measure.computedBy.formula];
57387
+ return this.compiledMeasureFormulas[pivotId][measure.id].formula;
57388
+ }
57389
+ getMeasureFullDependencies(pivotId, measure) {
57390
+ if (!measure.computedBy) {
57391
+ throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
57392
+ }
57393
+ return this.compiledMeasureFormulas[pivotId][measure.id].dependencies;
57367
57394
  }
57368
57395
  // -------------------------------------------------------------------------
57369
57396
  // Private
57370
57397
  // -------------------------------------------------------------------------
57371
57398
  addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
57372
57399
  this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
57373
- this.compileCalculatedMeasures(pivot.measures);
57400
+ this.compileCalculatedMeasures(pivotId, pivot.measures);
57374
57401
  this.history.update("formulaIds", formulaId, pivotId);
57375
57402
  this.history.update("nextFormulaId", this.nextFormulaId + 1);
57376
57403
  }
57377
- compileCalculatedMeasures(measures) {
57404
+ compileCalculatedMeasures(pivotId, measures) {
57378
57405
  for (const measure of measures) {
57379
57406
  if (measure.computedBy) {
57380
- const sheetId = measure.computedBy.sheetId;
57381
57407
  const compiledFormula = this.compileMeasureFormula(measure.computedBy.sheetId, measure.computedBy.formula);
57382
- this.history.update("compiledMeasureFormulas", sheetId, measure.computedBy.formula, compiledFormula);
57408
+ this.history.update("compiledMeasureFormulas", pivotId, measure.id, "formula", compiledFormula);
57383
57409
  }
57384
57410
  }
57411
+ for (const measure of measures) {
57412
+ if (measure.computedBy) {
57413
+ const dependencies = this.computeMeasureFullDependencies(pivotId, measure);
57414
+ this.history.update("compiledMeasureFormulas", pivotId, measure.id, "dependencies", dependencies);
57415
+ }
57416
+ }
57417
+ }
57418
+ computeMeasureFullDependencies(pivotId, measure, exploredMeasures = new Set()) {
57419
+ const rangeDependencies = [];
57420
+ const definition = this.getPivotCoreDefinition(pivotId);
57421
+ const formula = this.getMeasureCompiledFormula(pivotId, measure);
57422
+ exploredMeasures.add(measure.id);
57423
+ for (const token of formula.tokens) {
57424
+ if (token.type !== "SYMBOL") {
57425
+ continue;
57426
+ }
57427
+ const otherMeasure = definition.measures.find((measureCandidate) => getCanonicalSymbolName(measureCandidate.id) === token.value &&
57428
+ measure.id !== measureCandidate.id);
57429
+ if (!otherMeasure || exploredMeasures.has(otherMeasure.id) || !otherMeasure.computedBy) {
57430
+ continue;
57431
+ }
57432
+ rangeDependencies.push(...this.computeMeasureFullDependencies(pivotId, otherMeasure, exploredMeasures));
57433
+ }
57434
+ rangeDependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
57435
+ return rangeDependencies;
57385
57436
  }
57386
57437
  insertPivot(position, formulaId, table) {
57387
57438
  this.resizeSheet(position.sheetId, position, table);
@@ -57439,21 +57490,17 @@ class PivotCorePlugin extends CorePlugin {
57439
57490
  dependencies: rangeDependencies,
57440
57491
  };
57441
57492
  }
57442
- replaceMeasureFormula(sheetId, formulaString, newFormulaString) {
57443
- this.history.update("compiledMeasureFormulas", sheetId, formulaString, undefined);
57444
- this.history.update("compiledMeasureFormulas", sheetId, newFormulaString, this.compileMeasureFormula(sheetId, newFormulaString));
57445
- for (const pivotId in this.pivots) {
57446
- const pivot = this.pivots[pivotId];
57447
- if (!pivot) {
57448
- continue;
57449
- }
57450
- for (const measure of pivot.definition.measures) {
57451
- if (measure.computedBy?.formula === formulaString) {
57452
- const measureIndex = pivot.definition.measures.indexOf(measure);
57453
- this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", { formula: newFormulaString, sheetId });
57454
- }
57455
- }
57493
+ replaceMeasureFormula(pivotId, measure, newFormulaString) {
57494
+ const pivot = this.pivots[pivotId];
57495
+ if (!pivot) {
57496
+ return;
57456
57497
  }
57498
+ const measureIndex = pivot.definition.measures.indexOf(measure);
57499
+ this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", {
57500
+ formula: newFormulaString,
57501
+ sheetId: measure.computedBy.sheetId,
57502
+ });
57503
+ this.compileCalculatedMeasures(pivotId, pivot.definition.measures);
57457
57504
  }
57458
57505
  checkDuplicatedMeasureIds(definition) {
57459
57506
  const uniqueIds = new Set(definition.measures.map((m) => m.id));
@@ -60745,14 +60792,16 @@ const PERCENT_FORMAT = "0.00%";
60745
60792
  function withPivotPresentationLayer (PivotClass) {
60746
60793
  class PivotPresentationLayer extends PivotClass {
60747
60794
  getters;
60795
+ pivotId;
60748
60796
  cache = {};
60749
60797
  rankAsc = {};
60750
60798
  rankDesc = {};
60751
60799
  runningTotal = {};
60752
60800
  runningTotalInPercent = {};
60753
- constructor(custom, params) {
60801
+ constructor(pivotId, custom, params) {
60754
60802
  super(custom, params);
60755
60803
  this.getters = params.getters;
60804
+ this.pivotId = pivotId;
60756
60805
  }
60757
60806
  markAsDirtyForEvaluation() {
60758
60807
  this.cache = {};
@@ -60802,7 +60851,7 @@ function withPivotPresentationLayer (PivotClass) {
60802
60851
  return handleError(error, measure.aggregator.toUpperCase());
60803
60852
  }
60804
60853
  }
60805
- const formula = this.getters.getMeasureCompiledFormula(measure);
60854
+ const formula = this.getters.getMeasureCompiledFormula(this.pivotId, measure);
60806
60855
  const getSymbolValue = (symbolName) => {
60807
60856
  const { columns, rows } = this.definition;
60808
60857
  if (columns.find((col) => col.nameWithGranularity === symbolName)) {
@@ -61520,7 +61569,7 @@ class PivotUIPlugin extends UIPlugin {
61520
61569
  const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
61521
61570
  if (!(pivotId in this.pivots)) {
61522
61571
  const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
61523
- this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
61572
+ this.pivots[pivotId] = new Pivot(pivotId, this.custom, { definition, getters: this.getters });
61524
61573
  }
61525
61574
  else if (recreate) {
61526
61575
  this.pivots[pivotId].onDefinitionChange(definition);
@@ -74794,6 +74843,6 @@ exports.tokenColors = tokenColors;
74794
74843
  exports.tokenize = tokenize;
74795
74844
 
74796
74845
 
74797
- __info__.version = "18.0.53";
74798
- __info__.date = "2025-12-26T10:18:09.933Z";
74799
- __info__.hash = "7ca8390";
74846
+ __info__.version = "18.0.54";
74847
+ __info__.date = "2026-01-14T10:00:02.287Z";
74848
+ __info__.hash = "c0048a0";
@@ -4255,14 +4255,18 @@ interface Pivot$1 {
4255
4255
  definition: PivotCoreDefinition;
4256
4256
  formulaId: string;
4257
4257
  }
4258
+ interface MeasureState {
4259
+ formula: RangeCompiledFormula;
4260
+ dependencies: Range[];
4261
+ }
4258
4262
  interface CoreState {
4259
4263
  nextFormulaId: number;
4260
4264
  pivots: Record<UID, Pivot$1 | undefined>;
4261
4265
  formulaIds: Record<UID, string | undefined>;
4262
- compiledMeasureFormulas: Record<UID, Record<string, RangeCompiledFormula | undefined>>;
4266
+ compiledMeasureFormulas: Record<UID, Record<string, MeasureState | undefined>>;
4263
4267
  }
4264
4268
  declare class PivotCorePlugin extends CorePlugin<CoreState> implements CoreState {
4265
- static getters: readonly ["getPivotCoreDefinition", "getPivotDisplayName", "getPivotId", "getPivotFormulaId", "getPivotIds", "getMeasureCompiledFormula", "getPivotName", "isExistingPivot"];
4269
+ static getters: readonly ["getPivotCoreDefinition", "getPivotDisplayName", "getPivotId", "getPivotFormulaId", "getPivotIds", "getMeasureCompiledFormula", "getPivotName", "isExistingPivot", "getMeasureFullDependencies"];
4266
4270
  readonly nextFormulaId: number;
4267
4271
  readonly pivots: {
4268
4272
  [pivotId: UID]: Pivot$1 | undefined;
@@ -4270,7 +4274,7 @@ declare class PivotCorePlugin extends CorePlugin<CoreState> implements CoreState
4270
4274
  readonly formulaIds: {
4271
4275
  [formulaId: UID]: UID | undefined;
4272
4276
  };
4273
- readonly compiledMeasureFormulas: Record<UID, Record<string, RangeCompiledFormula>>;
4277
+ readonly compiledMeasureFormulas: Record<UID, Record<string, MeasureState>>;
4274
4278
  allowDispatch(cmd: CoreCommand): CommandResult.Success | CommandResult.NoChanges | CommandResult.PivotIdNotFound | CommandResult.EmptyName | CommandResult.InvalidDefinition;
4275
4279
  handle(cmd: CoreCommand): void;
4276
4280
  adaptRanges(applyChange: ApplyRangeChange): void;
@@ -4289,9 +4293,11 @@ declare class PivotCorePlugin extends CorePlugin<CoreState> implements CoreState
4289
4293
  getPivotFormulaId(pivotId: UID): string;
4290
4294
  getPivotIds(): UID[];
4291
4295
  isExistingPivot(pivotId: UID): boolean;
4292
- getMeasureCompiledFormula(measure: PivotCoreMeasure): RangeCompiledFormula;
4296
+ getMeasureCompiledFormula(pivotId: UID, measure: PivotCoreMeasure): RangeCompiledFormula;
4297
+ getMeasureFullDependencies(pivotId: UID, measure: PivotCoreMeasure): Range[];
4293
4298
  private addPivot;
4294
4299
  private compileCalculatedMeasures;
4300
+ private computeMeasureFullDependencies;
4295
4301
  private insertPivot;
4296
4302
  private resizeSheet;
4297
4303
  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.0.53
6
- * @date 2025-12-26T10:18:09.933Z
7
- * @hash 7ca8390
5
+ * @version 18.0.54
6
+ * @date 2026-01-14T10:00:02.287Z
7
+ * @hash c0048a0
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -18563,9 +18563,10 @@ function assertDomainLength(domain) {
18563
18563
  throw new EvaluationError(_t("Function PIVOT takes an even number of arguments."));
18564
18564
  }
18565
18565
  }
18566
- function addPivotDependencies(evalContext, coreDefinition, forMeasures) {
18566
+ function addPivotDependencies(evalContext, pivotId, forMeasures) {
18567
18567
  //TODO This function can be very costly when used with PIVOT.VALUE and PIVOT.HEADER
18568
18568
  const dependencies = [];
18569
+ const coreDefinition = evalContext.getters.getPivotCoreDefinition(pivotId);
18569
18570
  if (coreDefinition.type === "SPREADSHEET" && coreDefinition.dataSet) {
18570
18571
  const { sheetId, zone } = coreDefinition.dataSet;
18571
18572
  const xc = zoneToXc(zone);
@@ -18582,8 +18583,7 @@ function addPivotDependencies(evalContext, coreDefinition, forMeasures) {
18582
18583
  }
18583
18584
  for (const measure of forMeasures) {
18584
18585
  if (measure.computedBy) {
18585
- const formula = evalContext.getters.getMeasureCompiledFormula(measure);
18586
- dependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
18586
+ dependencies.push(...evalContext.getters.getMeasureFullDependencies(pivotId, measure));
18587
18587
  }
18588
18588
  }
18589
18589
  const originPosition = evalContext.__originCellPosition;
@@ -19024,7 +19024,7 @@ const PIVOT_VALUE = {
19024
19024
  assertDomainLength(domainArgs);
19025
19025
  const pivot = this.getters.getPivot(pivotId);
19026
19026
  const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
19027
- addPivotDependencies(this, coreDefinition, coreDefinition.measures.filter((m) => m.id === _measure));
19027
+ addPivotDependencies(this, pivotId, coreDefinition.measures.filter((m) => m.id === _measure));
19028
19028
  pivot.init({ reload: pivot.needsReevaluation });
19029
19029
  const error = pivot.assertIsValid({ throwOnError: false });
19030
19030
  if (error) {
@@ -19057,8 +19057,7 @@ const PIVOT_HEADER = {
19057
19057
  const _pivotId = getPivotId(_pivotFormulaId, this.getters);
19058
19058
  assertDomainLength(domainArgs);
19059
19059
  const pivot = this.getters.getPivot(_pivotId);
19060
- const coreDefinition = this.getters.getPivotCoreDefinition(_pivotId);
19061
- addPivotDependencies(this, coreDefinition, []);
19060
+ addPivotDependencies(this, _pivotId, []);
19062
19061
  pivot.init({ reload: pivot.needsReevaluation });
19063
19062
  const error = pivot.assertIsValid({ throwOnError: false });
19064
19063
  if (error) {
@@ -19112,7 +19111,7 @@ const PIVOT = {
19112
19111
  const pivotId = getPivotId(_pivotFormulaId, this.getters);
19113
19112
  const pivot = this.getters.getPivot(pivotId);
19114
19113
  const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
19115
- addPivotDependencies(this, coreDefinition, coreDefinition.measures);
19114
+ addPivotDependencies(this, pivotId, coreDefinition.measures);
19116
19115
  pivot.init({ reload: pivot.needsReevaluation });
19117
19116
  const error = pivot.assertIsValid({ throwOnError: false });
19118
19117
  if (error) {
@@ -42459,6 +42458,11 @@ class FindAndReplaceStore extends SpreadsheetStore {
42459
42458
  case "UPDATE_CELL":
42460
42459
  case "ACTIVATE_SHEET":
42461
42460
  this.isSearchDirty = true;
42461
+ if (this.searchOptions.specificRange) {
42462
+ this.searchOptions.specificRange = this.searchOptions.specificRange.clone({
42463
+ sheetId: this.getters.getActiveSheetId(),
42464
+ });
42465
+ }
42462
42466
  break;
42463
42467
  case "REPLACE_SEARCH":
42464
42468
  for (const match of cmd.matches) {
@@ -42864,9 +42868,20 @@ class FindAndReplacePanel extends Component {
42864
42868
  const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.dataRange);
42865
42869
  this.store.updateSearchOptions({ specificRange });
42866
42870
  }
42871
+ get specificRange() {
42872
+ const range = this.store.searchOptions.specificRange;
42873
+ return range ? this.env.model.getters.getRangeString(range, "forceSheetReference") : "";
42874
+ }
42867
42875
  get pendingSearch() {
42868
42876
  return this.updateSearchContent.isDebouncePending();
42869
42877
  }
42878
+ get selectionInputKey() {
42879
+ // Selections input are made to work with objects linked to a sheet id. They store the active sheet id at their creation,
42880
+ // and have specific behaviour linked to it (eg. go back to the initial sheet after confirmation).
42881
+ // We don't want all those behaviors here, so we force the recreation of the component when the active sheet changes.
42882
+ // The only drawback is that the input loses focus when changing sheet.
42883
+ return this.env.model.getters.getActiveSheetId();
42884
+ }
42870
42885
  }
42871
42886
 
42872
42887
  css /* scss */ `
@@ -57203,6 +57218,7 @@ class PivotCorePlugin extends CorePlugin {
57203
57218
  "getMeasureCompiledFormula",
57204
57219
  "getPivotName",
57205
57220
  "isExistingPivot",
57221
+ "getMeasureFullDependencies",
57206
57222
  ];
57207
57223
  nextFormulaId = 1;
57208
57224
  pivots = {};
@@ -57285,7 +57301,7 @@ class PivotCorePlugin extends CorePlugin {
57285
57301
  }
57286
57302
  case "UPDATE_PIVOT": {
57287
57303
  this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
57288
- this.compileCalculatedMeasures(cmd.pivot.measures);
57304
+ this.compileCalculatedMeasures(cmd.pivotId, cmd.pivot.measures);
57289
57305
  break;
57290
57306
  }
57291
57307
  }
@@ -57303,9 +57319,14 @@ class PivotCorePlugin extends CorePlugin {
57303
57319
  this.history.update("pivots", pivotId, "definition", newDefinition);
57304
57320
  }
57305
57321
  }
57306
- for (const sheetId in this.compiledMeasureFormulas) {
57307
- for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
57308
- const compiledFormula = this.compiledMeasureFormulas[sheetId][formulaString];
57322
+ for (const pivotId in this.compiledMeasureFormulas) {
57323
+ for (const measureId in this.compiledMeasureFormulas[pivotId]) {
57324
+ const measure = this.pivots[pivotId]?.definition.measures.find((m) => m.id === measureId);
57325
+ if (!measure || !measure.computedBy) {
57326
+ continue;
57327
+ }
57328
+ const sheetId = measure.computedBy.sheetId;
57329
+ const compiledFormula = this.compiledMeasureFormulas[pivotId][measureId].formula;
57309
57330
  const newDependencies = [];
57310
57331
  for (const range of compiledFormula.dependencies) {
57311
57332
  const change = applyChange(range);
@@ -57317,8 +57338,9 @@ class PivotCorePlugin extends CorePlugin {
57317
57338
  }
57318
57339
  }
57319
57340
  const newFormulaString = this.getters.getFormulaString(sheetId, compiledFormula.tokens, newDependencies);
57320
- if (newFormulaString !== formulaString) {
57321
- this.replaceMeasureFormula(sheetId, formulaString, newFormulaString);
57341
+ const oldFormulaString = measure.computedBy.formula;
57342
+ if (newFormulaString !== oldFormulaString) {
57343
+ this.replaceMeasureFormula(pivotId, measure, newFormulaString);
57322
57344
  }
57323
57345
  }
57324
57346
  }
@@ -57356,30 +57378,59 @@ class PivotCorePlugin extends CorePlugin {
57356
57378
  isExistingPivot(pivotId) {
57357
57379
  return pivotId in this.pivots;
57358
57380
  }
57359
- getMeasureCompiledFormula(measure) {
57381
+ getMeasureCompiledFormula(pivotId, measure) {
57360
57382
  if (!measure.computedBy) {
57361
57383
  throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
57362
57384
  }
57363
- const sheetId = measure.computedBy.sheetId;
57364
- return this.compiledMeasureFormulas[sheetId][measure.computedBy.formula];
57385
+ return this.compiledMeasureFormulas[pivotId][measure.id].formula;
57386
+ }
57387
+ getMeasureFullDependencies(pivotId, measure) {
57388
+ if (!measure.computedBy) {
57389
+ throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
57390
+ }
57391
+ return this.compiledMeasureFormulas[pivotId][measure.id].dependencies;
57365
57392
  }
57366
57393
  // -------------------------------------------------------------------------
57367
57394
  // Private
57368
57395
  // -------------------------------------------------------------------------
57369
57396
  addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
57370
57397
  this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
57371
- this.compileCalculatedMeasures(pivot.measures);
57398
+ this.compileCalculatedMeasures(pivotId, pivot.measures);
57372
57399
  this.history.update("formulaIds", formulaId, pivotId);
57373
57400
  this.history.update("nextFormulaId", this.nextFormulaId + 1);
57374
57401
  }
57375
- compileCalculatedMeasures(measures) {
57402
+ compileCalculatedMeasures(pivotId, measures) {
57376
57403
  for (const measure of measures) {
57377
57404
  if (measure.computedBy) {
57378
- const sheetId = measure.computedBy.sheetId;
57379
57405
  const compiledFormula = this.compileMeasureFormula(measure.computedBy.sheetId, measure.computedBy.formula);
57380
- this.history.update("compiledMeasureFormulas", sheetId, measure.computedBy.formula, compiledFormula);
57406
+ this.history.update("compiledMeasureFormulas", pivotId, measure.id, "formula", compiledFormula);
57381
57407
  }
57382
57408
  }
57409
+ for (const measure of measures) {
57410
+ if (measure.computedBy) {
57411
+ const dependencies = this.computeMeasureFullDependencies(pivotId, measure);
57412
+ this.history.update("compiledMeasureFormulas", pivotId, measure.id, "dependencies", dependencies);
57413
+ }
57414
+ }
57415
+ }
57416
+ computeMeasureFullDependencies(pivotId, measure, exploredMeasures = new Set()) {
57417
+ const rangeDependencies = [];
57418
+ const definition = this.getPivotCoreDefinition(pivotId);
57419
+ const formula = this.getMeasureCompiledFormula(pivotId, measure);
57420
+ exploredMeasures.add(measure.id);
57421
+ for (const token of formula.tokens) {
57422
+ if (token.type !== "SYMBOL") {
57423
+ continue;
57424
+ }
57425
+ const otherMeasure = definition.measures.find((measureCandidate) => getCanonicalSymbolName(measureCandidate.id) === token.value &&
57426
+ measure.id !== measureCandidate.id);
57427
+ if (!otherMeasure || exploredMeasures.has(otherMeasure.id) || !otherMeasure.computedBy) {
57428
+ continue;
57429
+ }
57430
+ rangeDependencies.push(...this.computeMeasureFullDependencies(pivotId, otherMeasure, exploredMeasures));
57431
+ }
57432
+ rangeDependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
57433
+ return rangeDependencies;
57383
57434
  }
57384
57435
  insertPivot(position, formulaId, table) {
57385
57436
  this.resizeSheet(position.sheetId, position, table);
@@ -57437,21 +57488,17 @@ class PivotCorePlugin extends CorePlugin {
57437
57488
  dependencies: rangeDependencies,
57438
57489
  };
57439
57490
  }
57440
- replaceMeasureFormula(sheetId, formulaString, newFormulaString) {
57441
- this.history.update("compiledMeasureFormulas", sheetId, formulaString, undefined);
57442
- this.history.update("compiledMeasureFormulas", sheetId, newFormulaString, this.compileMeasureFormula(sheetId, newFormulaString));
57443
- for (const pivotId in this.pivots) {
57444
- const pivot = this.pivots[pivotId];
57445
- if (!pivot) {
57446
- continue;
57447
- }
57448
- for (const measure of pivot.definition.measures) {
57449
- if (measure.computedBy?.formula === formulaString) {
57450
- const measureIndex = pivot.definition.measures.indexOf(measure);
57451
- this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", { formula: newFormulaString, sheetId });
57452
- }
57453
- }
57491
+ replaceMeasureFormula(pivotId, measure, newFormulaString) {
57492
+ const pivot = this.pivots[pivotId];
57493
+ if (!pivot) {
57494
+ return;
57454
57495
  }
57496
+ const measureIndex = pivot.definition.measures.indexOf(measure);
57497
+ this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", {
57498
+ formula: newFormulaString,
57499
+ sheetId: measure.computedBy.sheetId,
57500
+ });
57501
+ this.compileCalculatedMeasures(pivotId, pivot.definition.measures);
57455
57502
  }
57456
57503
  checkDuplicatedMeasureIds(definition) {
57457
57504
  const uniqueIds = new Set(definition.measures.map((m) => m.id));
@@ -60743,14 +60790,16 @@ const PERCENT_FORMAT = "0.00%";
60743
60790
  function withPivotPresentationLayer (PivotClass) {
60744
60791
  class PivotPresentationLayer extends PivotClass {
60745
60792
  getters;
60793
+ pivotId;
60746
60794
  cache = {};
60747
60795
  rankAsc = {};
60748
60796
  rankDesc = {};
60749
60797
  runningTotal = {};
60750
60798
  runningTotalInPercent = {};
60751
- constructor(custom, params) {
60799
+ constructor(pivotId, custom, params) {
60752
60800
  super(custom, params);
60753
60801
  this.getters = params.getters;
60802
+ this.pivotId = pivotId;
60754
60803
  }
60755
60804
  markAsDirtyForEvaluation() {
60756
60805
  this.cache = {};
@@ -60800,7 +60849,7 @@ function withPivotPresentationLayer (PivotClass) {
60800
60849
  return handleError(error, measure.aggregator.toUpperCase());
60801
60850
  }
60802
60851
  }
60803
- const formula = this.getters.getMeasureCompiledFormula(measure);
60852
+ const formula = this.getters.getMeasureCompiledFormula(this.pivotId, measure);
60804
60853
  const getSymbolValue = (symbolName) => {
60805
60854
  const { columns, rows } = this.definition;
60806
60855
  if (columns.find((col) => col.nameWithGranularity === symbolName)) {
@@ -61518,7 +61567,7 @@ class PivotUIPlugin extends UIPlugin {
61518
61567
  const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
61519
61568
  if (!(pivotId in this.pivots)) {
61520
61569
  const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
61521
- this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
61570
+ this.pivots[pivotId] = new Pivot(pivotId, this.custom, { definition, getters: this.getters });
61522
61571
  }
61523
61572
  else if (recreate) {
61524
61573
  this.pivots[pivotId].onDefinitionChange(definition);
@@ -74749,6 +74798,6 @@ const constants = {
74749
74798
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
74750
74799
 
74751
74800
 
74752
- __info__.version = "18.0.53";
74753
- __info__.date = "2025-12-26T10:18:09.933Z";
74754
- __info__.hash = "7ca8390";
74801
+ __info__.version = "18.0.54";
74802
+ __info__.date = "2026-01-14T10:00:02.287Z";
74803
+ __info__.hash = "c0048a0";