@odoo/o-spreadsheet 17.4.5 → 17.4.7

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 17.4.5
6
- * @date 2024-08-19T08:12:00.492Z
7
- * @hash 28579ad
5
+ * @version 17.4.7
6
+ * @date 2024-09-05T09:32:00.461Z
7
+ * @hash c14a4c9
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';
@@ -240,6 +240,7 @@ const PIVOT_TABLE_CONFIG = {
240
240
  bandedRows: true,
241
241
  bandedColumns: false,
242
242
  styleId: "TableStyleMedium5",
243
+ automaticAutofill: true,
243
244
  };
244
245
 
245
246
  //------------------------------------------------------------------------------
@@ -4558,6 +4559,17 @@ function reorderZone(zone) {
4558
4559
  }
4559
4560
  return zone;
4560
4561
  }
4562
+ function aggregatePositionsToZones(positions) {
4563
+ const result = {};
4564
+ for (const position of positions) {
4565
+ result[position.sheetId] ??= [];
4566
+ result[position.sheetId].push(positionToZone(position));
4567
+ }
4568
+ for (const sheetId in result) {
4569
+ result[sheetId] = recomputeZones(result[sheetId]);
4570
+ }
4571
+ return result;
4572
+ }
4561
4573
  /**
4562
4574
  * This function returns a zone with coordinates modified according to the change
4563
4575
  * applied to the zone. It may be possible to change the zone by resizing or moving
@@ -6773,9 +6785,11 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
6773
6785
  const targetCell = this.getters.getEvaluatedCell(target);
6774
6786
  const originFormat = origin.cell?.format ?? origin.evaluatedCell.format;
6775
6787
  if (clipboardOption?.pasteOption === "asValue") {
6776
- const locale = this.getters.getLocale();
6777
- const content = formatValue(origin.evaluatedCell.value, { locale });
6778
- this.dispatch("UPDATE_CELL", { ...target, content, format: originFormat });
6788
+ this.dispatch("UPDATE_CELL", {
6789
+ ...target,
6790
+ content: origin.evaluatedCell.value?.toString() || "",
6791
+ format: originFormat,
6792
+ });
6779
6793
  return;
6780
6794
  }
6781
6795
  if (clipboardOption?.pasteOption === "onlyFormat") {
@@ -28377,8 +28391,26 @@ const CREATE_PIVOT = (env) => {
28377
28391
  env.openSidePanel("PivotSidePanel", { pivotId });
28378
28392
  }
28379
28393
  };
28380
- const REINSERT_PIVOT_CHILDREN = (env) => env.model.getters.getPivotIds().map((pivotId, index) => ({
28381
- id: `reinsert_pivot_${env.model.getters.getPivotFormulaId(pivotId)}`,
28394
+ const REINSERT_DYNAMIC_PIVOT_CHILDREN = (env) => env.model.getters.getPivotIds().map((pivotId, index) => ({
28395
+ id: `reinsert_dynamic_pivot_${env.model.getters.getPivotFormulaId(pivotId)}`,
28396
+ name: env.model.getters.getPivotDisplayName(pivotId),
28397
+ sequence: index,
28398
+ execute: (env) => {
28399
+ const zone = env.model.getters.getSelectedZone();
28400
+ const table = env.model.getters.getPivot(pivotId).getTableStructure().export();
28401
+ env.model.dispatch("INSERT_PIVOT_WITH_TABLE", {
28402
+ pivotId,
28403
+ table,
28404
+ col: zone.left,
28405
+ row: zone.top,
28406
+ sheetId: env.model.getters.getActiveSheetId(),
28407
+ pivotMode: "dynamic",
28408
+ });
28409
+ env.model.dispatch("REFRESH_PIVOT", { id: pivotId });
28410
+ },
28411
+ }));
28412
+ const REINSERT_STATIC_PIVOT_CHILDREN = (env) => env.model.getters.getPivotIds().map((pivotId, index) => ({
28413
+ id: `reinsert_static_pivot_${env.model.getters.getPivotFormulaId(pivotId)}`,
28382
28414
  name: env.model.getters.getPivotDisplayName(pivotId),
28383
28415
  sequence: index,
28384
28416
  execute: (env) => {
@@ -28390,6 +28422,7 @@ const REINSERT_PIVOT_CHILDREN = (env) => env.model.getters.getPivotIds().map((pi
28390
28422
  col: zone.left,
28391
28423
  row: zone.top,
28392
28424
  sheetId: env.model.getters.getActiveSheetId(),
28425
+ pivotMode: "static",
28393
28426
  });
28394
28427
  env.model.dispatch("REFRESH_PIVOT", { id: pivotId });
28395
28428
  },
@@ -29258,12 +29291,20 @@ const splitToColumns = {
29258
29291
  isEnabled: (env) => env.model.getters.isSingleColSelected(),
29259
29292
  icon: "o-spreadsheet-Icon.SPLIT_TEXT",
29260
29293
  };
29261
- const reinsertPivotMenu = {
29262
- id: "reinsert_pivot",
29263
- name: _t("Re-insert pivot"),
29294
+ const reinsertDynamicPivotMenu = {
29295
+ id: "reinsert_dynamic_pivot",
29296
+ name: _t("Re-insert dynamic pivot"),
29297
+ sequence: 1020,
29298
+ icon: "o-spreadsheet-Icon.INSERT_PIVOT",
29299
+ children: [REINSERT_DYNAMIC_PIVOT_CHILDREN],
29300
+ isVisible: (env) => env.model.getters.getPivotIds().length > 0,
29301
+ };
29302
+ const reinsertStaticPivotMenu = {
29303
+ id: "reinsert_static_pivot",
29304
+ name: _t("Re-insert static pivot"),
29264
29305
  sequence: 1020,
29265
29306
  icon: "o-spreadsheet-Icon.INSERT_PIVOT",
29266
- children: [REINSERT_PIVOT_CHILDREN],
29307
+ children: [REINSERT_STATIC_PIVOT_CHILDREN],
29267
29308
  isVisible: (env) => env.model.getters.getPivotIds().length > 0,
29268
29309
  };
29269
29310
 
@@ -29272,7 +29313,8 @@ var ACTION_DATA = /*#__PURE__*/Object.freeze({
29272
29313
  createRemoveFilter: createRemoveFilter,
29273
29314
  createRemoveFilterTool: createRemoveFilterTool,
29274
29315
  dataCleanup: dataCleanup,
29275
- reinsertPivotMenu: reinsertPivotMenu,
29316
+ reinsertDynamicPivotMenu: reinsertDynamicPivotMenu,
29317
+ reinsertStaticPivotMenu: reinsertStaticPivotMenu,
29276
29318
  removeDuplicates: removeDuplicates,
29277
29319
  sortAscending: sortAscending,
29278
29320
  sortDescending: sortDescending,
@@ -30754,7 +30796,8 @@ topbarMenuRegistry
30754
30796
  };
30755
30797
  });
30756
30798
  })
30757
- .addChild("reinsert_pivot", ["data"], reinsertPivotMenu);
30799
+ .addChild("reinsert_dynamic_pivot", ["data"], reinsertDynamicPivotMenu)
30800
+ .addChild("reinsert_static_pivot", ["data"], reinsertStaticPivotMenu);
30758
30801
 
30759
30802
  class OTRegistry extends Registry {
30760
30803
  /**
@@ -35171,7 +35214,6 @@ class FindAndReplaceStore extends SpreadsheetStore {
35171
35214
  searchScope: "activeSheet",
35172
35215
  specificRange: undefined,
35173
35216
  };
35174
- updateSearchContent = debounce(this._updateSearchContent.bind(this), 200);
35175
35217
  constructor(get) {
35176
35218
  super(get);
35177
35219
  this.initialShowFormulaState = this.model.getters.shouldShowFormulas();
@@ -35180,7 +35222,6 @@ class FindAndReplaceStore extends SpreadsheetStore {
35180
35222
  highlightStore.register(this);
35181
35223
  this.onDispose(() => {
35182
35224
  this.model.dispatch("SET_FORMULA_VISIBILITY", { show: this.initialShowFormulaState });
35183
- this.updateSearchContent.stopDebounce();
35184
35225
  highlightStore.unRegister(this);
35185
35226
  });
35186
35227
  }
@@ -35194,7 +35235,7 @@ class FindAndReplaceStore extends SpreadsheetStore {
35194
35235
  return this.specificRangeMatches;
35195
35236
  }
35196
35237
  }
35197
- _updateSearchContent(toSearch) {
35238
+ updateSearchContent(toSearch) {
35198
35239
  this._updateSearch(toSearch, this.searchOptions);
35199
35240
  }
35200
35241
  updateSearchOptions(searchOptions) {
@@ -35210,9 +35251,6 @@ class FindAndReplaceStore extends SpreadsheetStore {
35210
35251
  selectNextMatch() {
35211
35252
  this.selectNextCell(Direction.next);
35212
35253
  }
35213
- get pendingSearch() {
35214
- return this.updateSearchContent.isDebouncePending();
35215
- }
35216
35254
  handle(cmd) {
35217
35255
  switch (cmd.type) {
35218
35256
  case "SET_FORMULA_VISIBILITY":
@@ -35538,6 +35576,7 @@ class FindAndReplacePanel extends Component {
35538
35576
  searchInput = useRef("searchInput");
35539
35577
  store;
35540
35578
  state;
35579
+ updateSearchContent;
35541
35580
  get hasSearchResult() {
35542
35581
  return this.store.selectedMatchIndex !== null;
35543
35582
  }
@@ -35569,12 +35608,14 @@ class FindAndReplacePanel extends Component {
35569
35608
  this.store = useLocalStore(FindAndReplaceStore);
35570
35609
  this.state = useState({ dataRange: "" });
35571
35610
  onMounted(() => this.searchInput.el?.focus());
35611
+ onWillUnmount(() => this.updateSearchContent.stopDebounce());
35612
+ this.updateSearchContent = debounce(this.store.updateSearchContent, 200);
35572
35613
  }
35573
35614
  onFocusSearch() {
35574
35615
  this.updateDataRange();
35575
35616
  }
35576
35617
  onSearchInput(ev) {
35577
- this.store.updateSearchContent(ev.target?.value || "");
35618
+ this.updateSearchContent(ev.target.value);
35578
35619
  }
35579
35620
  onKeydownSearch(ev) {
35580
35621
  if (ev.key === "Enter") {
@@ -35613,6 +35654,9 @@ class FindAndReplacePanel extends Component {
35613
35654
  const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.dataRange);
35614
35655
  this.store.updateSearchOptions({ specificRange });
35615
35656
  }
35657
+ get pendingSearch() {
35658
+ return this.updateSearchContent.isDebouncePending();
35659
+ }
35616
35660
  }
35617
35661
 
35618
35662
  css /* scss */ `
@@ -36666,6 +36710,12 @@ function orderDataEntriesKeys(groups, dimension) {
36666
36710
  * Used to order two values
36667
36711
  */
36668
36712
  function compareDimensionValues(dimension, a, b) {
36713
+ if (a === "null") {
36714
+ return dimension.order === "asc" ? 1 : -1;
36715
+ }
36716
+ if (b === "null") {
36717
+ return dimension.order === "asc" ? -1 : 1;
36718
+ }
36669
36719
  if (dimension.type === "integer" || dimension.type === "date") {
36670
36720
  return dimension.order === "asc" ? Number(a) - Number(b) : Number(b) - Number(a);
36671
36721
  }
@@ -37028,7 +37078,7 @@ class SpreadsheetPivot {
37028
37078
  if (cell.type === CellValueType.error) {
37029
37079
  throw new EvaluationError(_t("The pivot cannot be created because cell %s contains an error", toXC(col, row)));
37030
37080
  }
37031
- if (cell.type === CellValueType.empty) {
37081
+ if (cell.type === CellValueType.empty || cell.value === "") {
37032
37082
  throw new EvaluationError(_t("The pivot cannot be created because cell %s is empty", toXC(col, row)));
37033
37083
  }
37034
37084
  if (cell.value === "__count") {
@@ -37374,15 +37424,11 @@ class PivotSpreadsheetSidePanel extends Component {
37374
37424
  }
37375
37425
  onSelectionConfirmed() {
37376
37426
  if (this.state.range) {
37377
- const { sheetName, xc } = splitReference(this.state.range);
37378
- const sheetId = sheetName
37379
- ? this.env.model.getters.getSheetIdByName(sheetName)
37380
- : this.env.model.getters.getActiveSheetId();
37381
- if (!sheetId) {
37427
+ const range = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.range);
37428
+ if (range.invalidSheetName || range.invalidXc) {
37382
37429
  return;
37383
37430
  }
37384
- const zone = toZone(xc);
37385
- const dataSet = { sheetId, zone };
37431
+ const dataSet = { sheetId: range.sheetId, zone: range.zone };
37386
37432
  this.store.update({ dataSet });
37387
37433
  // Immediately apply the update to recompute the pivot fields
37388
37434
  this.store.applyUpdate();
@@ -38315,10 +38361,6 @@ class TablePanel extends Component {
38315
38361
  });
38316
38362
  }
38317
38363
  onRangeChanged(ranges) {
38318
- if (!ranges[0] || !ranges[0].match(rangeReference)) {
38319
- this.state.tableZoneErrors = ["InvalidRange" /* CommandResult.InvalidRange */];
38320
- return;
38321
- }
38322
38364
  const sheetId = this.env.model.getters.getActiveSheetId();
38323
38365
  this.state.tableXc = ranges[0];
38324
38366
  const newTableRange = this.env.model.getters.getRangeFromSheetXC(sheetId, this.state.tableXc);
@@ -38358,11 +38400,6 @@ class TablePanel extends Component {
38358
38400
  const newTableRange = updatedTable.range;
38359
38401
  this.state.tableXc = this.env.model.getters.getRangeString(newTableRange, sheetId);
38360
38402
  }
38361
- else {
38362
- const oldTableRange = this.props.table.range;
38363
- this.state.tableXc = this.env.model.getters.getRangeString(oldTableRange, sheetId);
38364
- }
38365
- this.state.tableZoneErrors = [];
38366
38403
  }
38367
38404
  deleteTable() {
38368
38405
  const sheetId = this.env.model.getters.getActiveSheetId();
@@ -44070,6 +44107,18 @@ function convertOperator(operator) {
44070
44107
  // -------------------------------------
44071
44108
  // WORKSHEET HELPERS
44072
44109
  // -------------------------------------
44110
+ function getCellType(value) {
44111
+ switch (typeof value) {
44112
+ case "boolean":
44113
+ return "b";
44114
+ case "string":
44115
+ return "str";
44116
+ case "number":
44117
+ return "n";
44118
+ default:
44119
+ return undefined;
44120
+ }
44121
+ }
44073
44122
  function convertHeightToExcel(height) {
44074
44123
  return Math.round(HEIGHT_FACTOR * height * 100) / 100;
44075
44124
  }
@@ -49249,7 +49298,10 @@ class HeaderSizePlugin extends CorePlugin {
49249
49298
  handle(cmd) {
49250
49299
  switch (cmd.type) {
49251
49300
  case "CREATE_SHEET": {
49252
- this.history.update("sizes", cmd.sheetId, { COL: [], ROW: [] });
49301
+ this.history.update("sizes", cmd.sheetId, {
49302
+ COL: Array(this.getters.getNumberCols(cmd.sheetId)).fill(undefined),
49303
+ ROW: Array(this.getters.getNumberRows(cmd.sheetId)).fill(undefined),
49304
+ });
49253
49305
  break;
49254
49306
  }
49255
49307
  case "DUPLICATE_SHEET":
@@ -54317,8 +54369,9 @@ class Evaluator {
54317
54369
  }
54318
54370
  getCellsDependingOn(positions) {
54319
54371
  const ranges = [];
54320
- for (const position of positions) {
54321
- ranges.push({ sheetId: position.sheetId, zone: positionToZone(position) });
54372
+ const zonesBySheetIds = aggregatePositionsToZones(positions);
54373
+ for (const sheetId in zonesBySheetIds) {
54374
+ ranges.push(...zonesBySheetIds[sheetId].map((zone) => ({ sheetId, zone })));
54322
54375
  }
54323
54376
  return this.formulaDependencies().getCellsDependingOn(ranges);
54324
54377
  }
@@ -55793,10 +55846,6 @@ class PivotUIPlugin extends UIPlugin {
55793
55846
  this.setupPivot(cmd.pivotId, { recreate: true });
55794
55847
  break;
55795
55848
  }
55796
- case "REMOVE_PIVOT": {
55797
- delete this.pivots[cmd.pivotId];
55798
- break;
55799
- }
55800
55849
  case "DELETE_SHEET":
55801
55850
  case "UPDATE_CELL": {
55802
55851
  this.unusedPivots = undefined;
@@ -55938,6 +55987,9 @@ class PivotUIPlugin extends UIPlugin {
55938
55987
  }
55939
55988
  }
55940
55989
  getPivot(pivotId) {
55990
+ if (!this.getters.isExistingPivot(pivotId)) {
55991
+ throw new Error(`pivot ${pivotId} not found`);
55992
+ }
55941
55993
  return this.pivots[pivotId];
55942
55994
  }
55943
55995
  isPivotUnused(pivotId) {
@@ -57229,9 +57281,9 @@ class Session extends EventBus {
57229
57281
  /**
57230
57282
  * Notify the server that the user client left the collaborative session
57231
57283
  */
57232
- leave(data) {
57284
+ async leave(data) {
57233
57285
  if (Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
57234
- this.snapshot(data());
57286
+ await this.snapshot(data());
57235
57287
  }
57236
57288
  delete this.clients[this.clientId];
57237
57289
  this.transportService.leave(this.clientId);
@@ -57244,12 +57296,12 @@ class Session extends EventBus {
57244
57296
  /**
57245
57297
  * Send a snapshot of the spreadsheet to the collaboration server
57246
57298
  */
57247
- snapshot(data) {
57299
+ async snapshot(data) {
57248
57300
  if (this.pendingMessages.length !== 0) {
57249
57301
  return;
57250
57302
  }
57251
57303
  const snapshotId = this.uuidGenerator.uuidv4();
57252
- this.transportService.sendMessage({
57304
+ await this.transportService.sendMessage({
57253
57305
  type: "SNAPSHOT",
57254
57306
  nextRevisionId: snapshotId,
57255
57307
  serverRevisionId: this.serverRevisionId,
@@ -57933,7 +57985,7 @@ class InsertPivotPlugin extends UIPlugin {
57933
57985
  this.duplicatePivotInNewSheet(cmd.pivotId, cmd.newPivotId, cmd.newSheetId);
57934
57986
  break;
57935
57987
  case "INSERT_PIVOT_WITH_TABLE":
57936
- this.insertPivotWithTable(cmd.sheetId, cmd.col, cmd.row, cmd.pivotId, cmd.table);
57988
+ this.insertPivotWithTable(cmd.sheetId, cmd.col, cmd.row, cmd.pivotId, cmd.table, cmd.pivotMode);
57937
57989
  break;
57938
57990
  }
57939
57991
  }
@@ -58009,26 +58061,44 @@ class InsertPivotPlugin extends UIPlugin {
58009
58061
  }
58010
58062
  return name;
58011
58063
  }
58012
- insertPivotWithTable(sheetId, col, row, pivotId, table) {
58064
+ insertPivotWithTable(sheetId, col, row, pivotId, table, mode) {
58013
58065
  const { cols, rows, measures, fieldsType } = table;
58014
58066
  const pivotTable = new SpreadsheetPivotTable(cols, rows, measures, fieldsType || {});
58067
+ const numberOfHeaders = pivotTable.columns.length - 1;
58015
58068
  this.resizeSheet(sheetId, col, row, pivotTable);
58016
58069
  const pivotFormulaId = this.getters.getPivotFormulaId(pivotId);
58017
- this.dispatch("UPDATE_CELL", {
58018
- sheetId,
58019
- col,
58020
- row,
58021
- content: `=PIVOT("${pivotFormulaId}")`,
58022
- });
58023
- const zone = {
58024
- left: col,
58025
- right: col,
58026
- top: row,
58027
- bottom: row,
58028
- };
58029
- const numberOfHeaders = pivotTable.columns.length - 1;
58070
+ let zone;
58071
+ if (mode === "dynamic") {
58072
+ this.dispatch("UPDATE_CELL", {
58073
+ sheetId,
58074
+ col,
58075
+ row,
58076
+ content: `=PIVOT(${pivotFormulaId})`,
58077
+ });
58078
+ zone = {
58079
+ left: col,
58080
+ right: col,
58081
+ top: row,
58082
+ bottom: row,
58083
+ };
58084
+ }
58085
+ else {
58086
+ this.dispatch("INSERT_PIVOT", {
58087
+ sheetId,
58088
+ col,
58089
+ row,
58090
+ pivotId,
58091
+ table: pivotTable.export(),
58092
+ });
58093
+ zone = {
58094
+ left: col,
58095
+ right: col + pivotTable.getNumberOfDataColumns(),
58096
+ top: row,
58097
+ bottom: row + numberOfHeaders + pivotTable.rows.length,
58098
+ };
58099
+ }
58030
58100
  this.dispatch("CREATE_TABLE", {
58031
- tableType: "dynamic",
58101
+ tableType: mode,
58032
58102
  sheetId,
58033
58103
  ranges: [this.getters.getRangeDataFromZone(sheetId, zone)],
58034
58104
  config: { ...PIVOT_TABLE_CONFIG, numberOfHeaders },
@@ -59409,6 +59479,7 @@ class ClipboardPlugin extends UIPlugin {
59409
59479
  this.status = "invisible";
59410
59480
  if (this._isCutOperation) {
59411
59481
  this.copiedData = undefined;
59482
+ this._isCutOperation = false;
59412
59483
  }
59413
59484
  break;
59414
59485
  }
@@ -59506,6 +59577,7 @@ class ClipboardPlugin extends UIPlugin {
59506
59577
  }
59507
59578
  case "ACTIVATE_PAINT_FORMAT": {
59508
59579
  const zones = this.getters.getSelectedZones();
59580
+ this._isCutOperation = false;
59509
59581
  this.copiedData = this.copy(zones);
59510
59582
  this.status = "visible";
59511
59583
  if (cmd.persistent) {
@@ -60228,6 +60300,8 @@ class GridSelectionPlugin extends UIPlugin {
60228
60300
  this.selectedFigureId = null;
60229
60301
  break;
60230
60302
  }
60303
+ }
60304
+ finalize() {
60231
60305
  /** Any change to the selection has to be reflected in the selection processor. */
60232
60306
  this.selection.resetDefaultAnchor(this, deepCopy(this.gridSelection.anchor));
60233
60307
  }
@@ -61009,7 +61083,6 @@ class SheetViewPlugin extends UIPlugin {
61009
61083
  }
61010
61084
  }
61011
61085
  handle(cmd) {
61012
- this.cleanViewports();
61013
61086
  // changing the evaluation can hide/show rows because of data filters
61014
61087
  if (invalidateEvaluationCommands.has(cmd.type)) {
61015
61088
  for (const sheetId of this.getters.getSheetIds()) {
@@ -61025,6 +61098,7 @@ class SheetViewPlugin extends UIPlugin {
61025
61098
  break;
61026
61099
  case "UNDO":
61027
61100
  case "REDO":
61101
+ this.cleanViewports();
61028
61102
  for (const sheetId of this.getters.getSheetIds()) {
61029
61103
  this.sheetsWithDirtyViewports.add(sheetId);
61030
61104
  }
@@ -61079,6 +61153,9 @@ class SheetViewPlugin extends UIPlugin {
61079
61153
  }
61080
61154
  }
61081
61155
  break;
61156
+ case "DELETE_SHEET":
61157
+ this.cleanViewports();
61158
+ break;
61082
61159
  case "ACTIVATE_SHEET":
61083
61160
  this.sheetsWithDirtyViewports.add(cmd.sheetIdTo);
61084
61161
  break;
@@ -62366,6 +62443,17 @@ css /* scss */ `
62366
62443
  .o-bottom-bar-fade-in {
62367
62444
  background-image: linear-gradient(90deg, #cfcfcf, transparent 1%);
62368
62445
  }
62446
+
62447
+ .o-sheet-list {
62448
+ overflow-y: hidden;
62449
+ overflow-x: auto;
62450
+
62451
+ &::-webkit-scrollbar {
62452
+ display: none; /* Chrome */
62453
+ }
62454
+ -ms-overflow-style: none; /* IE and Edge */
62455
+ scrollbar-width: none; /* Firefox */
62456
+ }
62369
62457
  }
62370
62458
 
62371
62459
  .o-bottom-bar-arrows {
@@ -64339,7 +64427,7 @@ class Spreadsheet extends Component {
64339
64427
 
64340
64428
  class LocalTransportService {
64341
64429
  listeners = [];
64342
- sendMessage(message) {
64430
+ async sendMessage(message) {
64343
64431
  for (const { callback } of this.listeners) {
64344
64432
  callback(message);
64345
64433
  }
@@ -66432,17 +66520,13 @@ function addFormula(cell) {
66432
66520
  if (!formula) {
66433
66521
  return { attrs: [], node: escapeXml `` };
66434
66522
  }
66435
- const attrs = [];
66436
- let node = escapeXml ``;
66437
- let cycle = escapeXml ``;
66438
- const XlsxFormula = adaptFormulaToExcel(formula);
66439
- // hack for cycles : if we don't set a value (be it 0 or #VALUE!), it will appear as invisible on excel,
66440
- // Making it very hard for the client to find where the recursion is.
66441
- if (cell.value === CellErrorType.CircularDependency) {
66442
- attrs.push(["t", "str"]);
66443
- cycle = escapeXml /*xml*/ `<v>${cell.value}</v>`;
66523
+ const type = getCellType(cell.value);
66524
+ if (type === undefined) {
66525
+ return { attrs: [], node: escapeXml `` };
66444
66526
  }
66445
- node = escapeXml /*xml*/ `<f>${XlsxFormula}</f>${cycle}`;
66527
+ const attrs = [["t", type]];
66528
+ const XlsxFormula = adaptFormulaToExcel(formula);
66529
+ const node = escapeXml /*xml*/ `<f>${XlsxFormula}</f><v>${cell.value}</v>`;
66446
66530
  return { attrs, node };
66447
66531
  }
66448
66532
  function addContent(content, sharedStrings, forceString = false) {
@@ -67856,8 +67940,8 @@ class Model extends EventBus {
67856
67940
  joinSession() {
67857
67941
  this.session.join(this.config.client);
67858
67942
  }
67859
- leaveSession() {
67860
- this.session.leave(lazy(() => this.exportData()));
67943
+ async leaveSession() {
67944
+ await this.session.leave(lazy(() => this.exportData()));
67861
67945
  }
67862
67946
  setupUiPlugin(Plugin) {
67863
67947
  const plugin = new Plugin(this.uiPluginConfig);
@@ -68416,6 +68500,6 @@ const constants = {
68416
68500
  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 };
68417
68501
 
68418
68502
 
68419
- __info__.version = "17.4.5";
68420
- __info__.date = "2024-08-19T08:12:00.492Z";
68421
- __info__.hash = "28579ad";
68503
+ __info__.version = "17.4.7";
68504
+ __info__.date = "2024-09-05T09:32:00.461Z";
68505
+ __info__.hash = "c14a4c9";