@odoo/o-spreadsheet 19.0.15 → 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.15
6
- * @date 2025-12-26T10:19:23.408Z
7
- * @hash fe625c9
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),
@@ -51369,7 +51368,6 @@ class GridOverlay extends Component {
51369
51368
  onGridMoved: Function,
51370
51369
  gridOverlayDimensions: String,
51371
51370
  slots: { type: Object, optional: true },
51372
- getGridSize: Function,
51373
51371
  };
51374
51372
  static components = {
51375
51373
  FiguresContainer,
@@ -51388,14 +51386,7 @@ class GridOverlay extends Component {
51388
51386
  setup() {
51389
51387
  useCellHovered(this.env, this.gridOverlay);
51390
51388
  const resizeObserver = new ResizeObserver(() => {
51391
- const boundingRect = this.gridOverlayEl.getBoundingClientRect();
51392
- const { width, height } = this.props.getGridSize();
51393
- this.props.onGridResized({
51394
- x: boundingRect.left,
51395
- y: boundingRect.top,
51396
- height: height,
51397
- width: width,
51398
- });
51389
+ this.props.onGridResized();
51399
51390
  });
51400
51391
  onMounted(() => {
51401
51392
  resizeObserver.observe(this.gridOverlayEl);
@@ -57883,6 +57874,12 @@ class FindAndReplaceStore extends SpreadsheetStore {
57883
57874
  case "ACTIVATE_SHEET":
57884
57875
  this.isSearchDirty = true;
57885
57876
  this.shouldFinalizeUpdateSelection = true;
57877
+ if (this.searchOptions.specificRange) {
57878
+ this.searchOptions.specificRange = {
57879
+ ...this.searchOptions.specificRange,
57880
+ sheetId: this.getters.getActiveSheetId(),
57881
+ };
57882
+ }
57886
57883
  break;
57887
57884
  case "REPLACE_SEARCH":
57888
57885
  for (const match of cmd.matches) {
@@ -58302,9 +58299,20 @@ class FindAndReplacePanel extends Component {
58302
58299
  const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.dataRange);
58303
58300
  this.store.updateSearchOptions({ specificRange });
58304
58301
  }
58302
+ get specificRange() {
58303
+ const range = this.store.searchOptions.specificRange;
58304
+ return range ? this.env.model.getters.getRangeString(range, "forceSheetReference") : "";
58305
+ }
58305
58306
  get pendingSearch() {
58306
58307
  return this.updateSearchContent.isDebouncePending();
58307
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
+ }
58308
58316
  }
58309
58317
 
58310
58318
  css /* scss */ `
@@ -61419,7 +61427,8 @@ class Grid extends Component {
61419
61427
  });
61420
61428
  return !(rect.width === 0 || rect.height === 0);
61421
61429
  }
61422
- onGridResized({ height, width }) {
61430
+ onGridResized() {
61431
+ const { height, width } = this.props.getGridSize();
61423
61432
  this.env.model.dispatch("RESIZE_SHEETVIEW", {
61424
61433
  width: width - HEADER_WIDTH,
61425
61434
  height: height - HEADER_HEIGHT,
@@ -67613,6 +67622,7 @@ class PivotCorePlugin extends CorePlugin {
67613
67622
  "getMeasureCompiledFormula",
67614
67623
  "getPivotName",
67615
67624
  "isExistingPivot",
67625
+ "getMeasureFullDependencies",
67616
67626
  ];
67617
67627
  nextFormulaId = 1;
67618
67628
  pivots = {};
@@ -67695,7 +67705,7 @@ class PivotCorePlugin extends CorePlugin {
67695
67705
  }
67696
67706
  case "UPDATE_PIVOT": {
67697
67707
  this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
67698
- this.compileCalculatedMeasures(cmd.pivot.measures);
67708
+ this.compileCalculatedMeasures(cmd.pivotId, cmd.pivot.measures);
67699
67709
  break;
67700
67710
  }
67701
67711
  }
@@ -67713,9 +67723,14 @@ class PivotCorePlugin extends CorePlugin {
67713
67723
  this.history.update("pivots", pivotId, "definition", newDefinition);
67714
67724
  }
67715
67725
  }
67716
- for (const sheetId in this.compiledMeasureFormulas) {
67717
- for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
67718
- 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;
67719
67734
  const newDependencies = [];
67720
67735
  for (const range of compiledFormula.dependencies) {
67721
67736
  const change = applyChange(range);
@@ -67727,8 +67742,9 @@ class PivotCorePlugin extends CorePlugin {
67727
67742
  }
67728
67743
  }
67729
67744
  const newFormulaString = this.getters.getFormulaString(sheetId, compiledFormula.tokens, newDependencies);
67730
- if (newFormulaString !== formulaString) {
67731
- this.replaceMeasureFormula(sheetId, formulaString, newFormulaString);
67745
+ const oldFormulaString = measure.computedBy.formula;
67746
+ if (newFormulaString !== oldFormulaString) {
67747
+ this.replaceMeasureFormula(pivotId, measure, newFormulaString);
67732
67748
  }
67733
67749
  }
67734
67750
  }
@@ -67766,31 +67782,60 @@ class PivotCorePlugin extends CorePlugin {
67766
67782
  isExistingPivot(pivotId) {
67767
67783
  return pivotId in this.pivots;
67768
67784
  }
67769
- getMeasureCompiledFormula(measure) {
67785
+ getMeasureCompiledFormula(pivotId, measure) {
67770
67786
  if (!measure.computedBy) {
67771
67787
  throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
67772
67788
  }
67773
- const sheetId = measure.computedBy.sheetId;
67774
- 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;
67775
67796
  }
67776
67797
  // -------------------------------------------------------------------------
67777
67798
  // Private
67778
67799
  // -------------------------------------------------------------------------
67779
67800
  addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
67780
67801
  this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
67781
- this.compileCalculatedMeasures(pivot.measures);
67802
+ this.compileCalculatedMeasures(pivotId, pivot.measures);
67782
67803
  this.history.update("formulaIds", formulaId, pivotId);
67783
67804
  this.history.update("nextFormulaId", this.nextFormulaId + 1);
67784
67805
  }
67785
- compileCalculatedMeasures(measures) {
67806
+ compileCalculatedMeasures(pivotId, measures) {
67786
67807
  for (const measure of measures) {
67787
67808
  if (measure.computedBy) {
67788
- const sheetId = measure.computedBy.sheetId;
67789
67809
  const compiledFormula = this.compileMeasureFormula(measure.computedBy.sheetId, measure.computedBy.formula);
67790
- this.history.update("compiledMeasureFormulas", sheetId, measure.computedBy.formula, compiledFormula);
67810
+ this.history.update("compiledMeasureFormulas", pivotId, measure.id, "formula", compiledFormula);
67811
+ }
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);
67791
67817
  }
67792
67818
  }
67793
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;
67838
+ }
67794
67839
  insertPivot(position, formulaId, table) {
67795
67840
  this.resizeSheet(position.sheetId, position, table);
67796
67841
  const pivotCells = table.getPivotCells();
@@ -67849,21 +67894,17 @@ class PivotCorePlugin extends CorePlugin {
67849
67894
  dependencies: rangeDependencies,
67850
67895
  };
67851
67896
  }
67852
- replaceMeasureFormula(sheetId, formulaString, newFormulaString) {
67853
- this.history.update("compiledMeasureFormulas", sheetId, formulaString, undefined);
67854
- this.history.update("compiledMeasureFormulas", sheetId, newFormulaString, this.compileMeasureFormula(sheetId, newFormulaString));
67855
- for (const pivotId in this.pivots) {
67856
- const pivot = this.pivots[pivotId];
67857
- if (!pivot) {
67858
- continue;
67859
- }
67860
- for (const measure of pivot.definition.measures) {
67861
- if (measure.computedBy?.formula === formulaString) {
67862
- const measureIndex = pivot.definition.measures.indexOf(measure);
67863
- this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", { formula: newFormulaString, sheetId });
67864
- }
67865
- }
67897
+ replaceMeasureFormula(pivotId, measure, newFormulaString) {
67898
+ const pivot = this.pivots[pivotId];
67899
+ if (!pivot) {
67900
+ return;
67866
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);
67867
67908
  }
67868
67909
  checkSortedColumnInMeasures(definition) {
67869
67910
  const measures = definition.measures.map((measure) => measure.id);
@@ -71713,14 +71754,16 @@ const PERCENT_FORMAT = "0.00%";
71713
71754
  function withPivotPresentationLayer (PivotClass) {
71714
71755
  class PivotPresentationLayer extends PivotClass {
71715
71756
  getters;
71757
+ pivotId;
71716
71758
  cache = {};
71717
71759
  rankAsc = {};
71718
71760
  rankDesc = {};
71719
71761
  runningTotal = {};
71720
71762
  runningTotalInPercent = {};
71721
- constructor(custom, params) {
71763
+ constructor(pivotId, custom, params) {
71722
71764
  super(custom, params);
71723
71765
  this.getters = params.getters;
71766
+ this.pivotId = pivotId;
71724
71767
  }
71725
71768
  markAsDirtyForEvaluation() {
71726
71769
  this.cache = {};
@@ -71770,7 +71813,7 @@ function withPivotPresentationLayer (PivotClass) {
71770
71813
  return handleError(error, measure.aggregator.toUpperCase());
71771
71814
  }
71772
71815
  }
71773
- const formula = this.getters.getMeasureCompiledFormula(measure);
71816
+ const formula = this.getters.getMeasureCompiledFormula(this.pivotId, measure);
71774
71817
  const getSymbolValue = (symbolName) => {
71775
71818
  const { columns, rows } = this.definition;
71776
71819
  if (columns.find((col) => col.nameWithGranularity === symbolName)) {
@@ -72525,7 +72568,7 @@ class PivotUIPlugin extends CoreViewPlugin {
72525
72568
  const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
72526
72569
  if (!(pivotId in this.pivots)) {
72527
72570
  const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
72528
- this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
72571
+ this.pivots[pivotId] = new Pivot(pivotId, this.custom, { definition, getters: this.getters });
72529
72572
  }
72530
72573
  else if (recreate) {
72531
72574
  this.pivots[pivotId].onDefinitionChange(definition);
@@ -74417,7 +74460,7 @@ class Session extends EventBus {
74417
74460
  }
74418
74461
  delete this.clients[this.clientId];
74419
74462
  this.transportService.leave(this.clientId);
74420
- this.transportService.sendMessage({
74463
+ this.sendToTransport({
74421
74464
  type: "CLIENT_LEFT",
74422
74465
  clientId: this.clientId,
74423
74466
  version: MESSAGE_VERSION,
@@ -74431,7 +74474,7 @@ class Session extends EventBus {
74431
74474
  return;
74432
74475
  }
74433
74476
  const snapshotId = this.uuidGenerator.uuidv4();
74434
- await this.transportService.sendMessage({
74477
+ await this.sendToTransport({
74435
74478
  type: "SNAPSHOT",
74436
74479
  nextRevisionId: snapshotId,
74437
74480
  serverRevisionId: this.serverRevisionId,
@@ -74479,10 +74522,14 @@ class Session extends EventBus {
74479
74522
  const type = currentPosition ? "CLIENT_MOVED" : "CLIENT_JOINED";
74480
74523
  const client = this.getCurrentClient();
74481
74524
  this.clients[this.clientId] = { ...client, position };
74482
- this.transportService.sendMessage({
74525
+ this.sendToTransport({
74483
74526
  type,
74484
74527
  version: MESSAGE_VERSION,
74485
74528
  client: { ...client, position },
74529
+ }).then(() => {
74530
+ if (this.pendingMessages.length > 0 && !this.waitingAck) {
74531
+ this.sendPendingMessage();
74532
+ }
74486
74533
  });
74487
74534
  }
74488
74535
  /**
@@ -74563,7 +74610,7 @@ class Session extends EventBus {
74563
74610
  if (client) {
74564
74611
  const { position } = client;
74565
74612
  if (position) {
74566
- this.transportService.sendMessage({
74613
+ this.sendToTransport({
74567
74614
  type: "CLIENT_MOVED",
74568
74615
  version: MESSAGE_VERSION,
74569
74616
  client: { ...client, position },
@@ -74584,6 +74631,10 @@ class Session extends EventBus {
74584
74631
  }
74585
74632
  this.sendPendingMessage();
74586
74633
  }
74634
+ async sendToTransport(message) {
74635
+ // wrap in an async function to ensure it returns a promise
74636
+ return this.transportService.sendMessage(message);
74637
+ }
74587
74638
  /**
74588
74639
  * Send the next pending message
74589
74640
  */
@@ -74612,9 +74663,14 @@ class Session extends EventBus {
74612
74663
  ${JSON.stringify(message)}`);
74613
74664
  }
74614
74665
  this.waitingAck = true;
74615
- this.transportService.sendMessage({
74666
+ this.sendToTransport({
74616
74667
  ...message,
74617
74668
  serverRevisionId: this.serverRevisionId,
74669
+ }).catch((e) => {
74670
+ if (!(e instanceof ClientDisconnectedError)) {
74671
+ throw e.cause || e;
74672
+ }
74673
+ this.waitingAck = false;
74618
74674
  });
74619
74675
  }
74620
74676
  acknowledge(message) {
@@ -82120,10 +82176,8 @@ class SpreadsheetDashboard extends Component {
82120
82176
  });
82121
82177
  }
82122
82178
  get gridContainer() {
82123
- const sheetId = this.env.model.getters.getActiveSheetId();
82124
- const { right } = this.env.model.getters.getSheetZone(sheetId);
82125
- const { end } = this.env.model.getters.getColDimensions(sheetId, right);
82126
- return cssPropertiesToCss({ "max-width": `${end}px` });
82179
+ const maxWidth = this.getMaxSheetWidth();
82180
+ return cssPropertiesToCss({ "max-width": `${maxWidth}px` });
82127
82181
  }
82128
82182
  get gridOverlayDimensions() {
82129
82183
  return cssPropertiesToCss({
@@ -82155,10 +82209,12 @@ class SpreadsheetDashboard extends Component {
82155
82209
  onClosePopover() {
82156
82210
  this.cellPopovers.close();
82157
82211
  }
82158
- onGridResized({ height, width }) {
82212
+ onGridResized() {
82213
+ const { height, width } = this.props.getGridSize();
82214
+ const maxWidth = this.getMaxSheetWidth();
82159
82215
  this.env.model.dispatch("RESIZE_SHEETVIEW", {
82160
- width: width,
82161
- height: height,
82216
+ width: Math.min(maxWidth, width),
82217
+ height,
82162
82218
  gridOffsetX: 0,
82163
82219
  gridOffsetY: 0,
82164
82220
  });
@@ -82176,6 +82232,11 @@ class SpreadsheetDashboard extends Component {
82176
82232
  ...this.env.model.getters.getSheetViewDimensionWithHeaders(),
82177
82233
  };
82178
82234
  }
82235
+ getMaxSheetWidth() {
82236
+ const sheetId = this.env.model.getters.getActiveSheetId();
82237
+ const { right } = this.env.model.getters.getSheetZone(sheetId);
82238
+ return this.env.model.getters.getColDimensions(sheetId, right).end;
82239
+ }
82179
82240
  }
82180
82241
 
82181
82242
  css /* scss */ `
@@ -84417,22 +84478,20 @@ class Spreadsheet extends Component {
84417
84478
  return this.env.model.getters.getVisibleGroupLayers(sheetId, "COL");
84418
84479
  }
84419
84480
  getGridSize() {
84420
- const topBarHeight = this.spreadsheetRef.el
84421
- ?.querySelector(".o-spreadsheet-topbar-wrapper")
84422
- ?.getBoundingClientRect().height || 0;
84423
- const bottomBarHeight = this.spreadsheetRef.el
84424
- ?.querySelector(".o-spreadsheet-bottombar-wrapper")
84425
- ?.getBoundingClientRect().height || 0;
84426
- const gridWidth = this.spreadsheetRef.el?.querySelector(".o-grid")?.getBoundingClientRect().width || 0;
84427
- const gridHeight = (this.spreadsheetRef.el?.getBoundingClientRect().height || 0) -
84428
- (this.spreadsheetRef.el?.querySelector(".o-column-groups")?.getBoundingClientRect().height ||
84429
- 0) -
84430
- topBarHeight -
84431
- bottomBarHeight;
84432
- return {
84433
- width: Math.max(gridWidth - SCROLLBAR_WIDTH, 0),
84434
- height: Math.max(gridHeight - SCROLLBAR_WIDTH, 0),
84435
- };
84481
+ const el = this.spreadsheetRef.el;
84482
+ if (!el) {
84483
+ return { width: 0, height: 0 };
84484
+ }
84485
+ const getHeight = (selector) => el.querySelector(selector)?.getBoundingClientRect().height || 0;
84486
+ const getWidth = (selector) => el.querySelector(selector)?.getBoundingClientRect().width || 0;
84487
+ const rect = el.getBoundingClientRect();
84488
+ const topBarHeight = getHeight(".o-spreadsheet-topbar-wrapper");
84489
+ const bottomBarHeight = getHeight(".o-spreadsheet-bottombar-wrapper");
84490
+ const colGroupHeight = getHeight(".o-column-groups");
84491
+ const gridWidth = getWidth(".o-grid");
84492
+ const width = Math.max(gridWidth - SCROLLBAR_WIDTH, 0);
84493
+ const height = Math.max(rect.height - topBarHeight - bottomBarHeight - colGroupHeight - SCROLLBAR_WIDTH, 0);
84494
+ return { width, height };
84436
84495
  }
84437
84496
  }
84438
84497
 
@@ -84445,7 +84504,7 @@ class ReadonlyTransportFilter {
84445
84504
  if (message.type === "CLIENT_JOINED" ||
84446
84505
  message.type === "CLIENT_LEFT" ||
84447
84506
  message.type === "CLIENT_MOVED") {
84448
- this.transportService.sendMessage(message);
84507
+ await this.transportService.sendMessage(message);
84449
84508
  }
84450
84509
  // ignore all other messages
84451
84510
  }
@@ -89064,6 +89123,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
89064
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 };
89065
89124
 
89066
89125
 
89067
- __info__.version = "19.0.15";
89068
- __info__.date = "2025-12-26T10:19:23.408Z";
89069
- __info__.hash = "fe625c9";
89126
+ __info__.version = "19.0.17";
89127
+ __info__.date = "2026-01-14T10:01:24.044Z";
89128
+ __info__.hash = "2165bad";